Search results

오늘의 삽질

분명히 로컬 개발환경에서는 의도한대로 Federation 잘 동작하고 있는데, 왜 프로덕션에서는 팔로우도 제대로 동작안하고, Create(Note) 액티비티는 왜 제대로 안 들어오고 /users/inbox 라는 이상한 엉뚱한 경로로 들어오나하고 한참을 까봤다. sharedInbox 경로만 엉뚱한 URL 패턴을 가지고 있었다.... 프론트엔드/백엔드 분리하긴 했다만, 리다이렉션도 제대로 안 걸어둬서 생긴 오류였다. 아이고두야....

해당 에러를 고친 commit인데 내가 봐도 어이가 없다.
1
2

웹 기반 코딩에이전트가 자동사냥 돌리면서 피드백루프를 만들 수 있으려면 두가지 전제가 필요하다.

  1. 빌드가 되는 코드인지 검사하는 프로세스
  2. 실제로 동작이 되는지 확인이 될 수 있게 하는 자동화된 배포

돌아가는지도 모르는 코드로 자동사냥하면 무슨 의미가 있나...

문서화도 문서화대로 해둘 필요는 있겠지만, 자동화된 배포 프로세스부터 먼저 갖추고 자동사냥 돌릴 수 있게 해야겠다. 근데, 는 불가피하게 수동배포라서 못할 것 같고....

2
3

Codex로 되던게 이제는 클로드로도 되니까 자동사냥은 사실상 디폴트가 되어가는듯. 근데, 자동사냥 어디다 시키지(.....) 에다가 시키자니 직접 눈으로 확인해야할 요소도 많은데다가 federation도 신경써야 하고, 그렇다고 docs를 보강하자니 내가 의도적으로 수련해야하는 영역을 떠넘기긴 애매하고

3
5
4

관련 개발 TODO:

  1. 인메모리 큐로 처리되고 있는 cosmoslidde의 연합우주용 메세지 큐를 이미 쓰고있는 postgresql를 사용하도록 수정
  2. 별도의 배치 작업을 위한 메세지 큐 구현(1과 별도의 테이블을 postgresql에 넣으면 해결될 듯?)
  3. 현재 모든 오브젝트의 리스트를 긁어오는 list API를 수정
1
5
1
1

음... 기여하려는데, 이미지 생성 프로세싱(썸네일 생성)을 기존 백엔드 컨테이너에서 할지, 아니면 별도의 컨테이너를 만들어서 거기서 할 지 고민이 되네. 확장성을 생각하면, 당연히 후자이긴 한데. 비슷한 거 구현해본 분들의 고견을 듣고 싶다.

0

작업일지 251012

이번에는 Announce 액티비티 지원하는 작업을 진행 중인데, 해커스펍이 어떻게 구현되어 있는지 하나하나 뜯어보면서 작업 중이다. 고려해야 할 사항이 몇 가지 있는데... 당장은 쉬운 것 순서대로 작업할 것들을 정리하고 있다.

  • Phase 1 : 내가 팔로하고 있는 원격 계정에서 전달되는 Announce 액티비티를 인박스에서 수신하는 과정을 핸들링한다. (원격에서는 followers에 cc 걸어서 Announce 액티비티를 전송하기 때문)
  • Phase 2 : 나를 팔로하고 있는 로컬 인스턴스 계정의 글을 재공유하는 매커니즘을 구현한다.
  • Phase 3 : 나를 팔로하고 있는 원격 계정의 inbox에 Announce 액티비티를 전달하는 매커니즘을 구현한다.

지금은 Phase 1에 신경쓰고 있는 상황. 허나, Phase 1을 작업하고 있는 과정에서 병목이 생겼다. 다행히 해결했다만.

Follow 액티비티가 언제부턴가 전송이 안되고 있어서 왜 그런가 했는데, 프로덕션 배포하는 과정에서 federation 옵션을 바꾼게 화근이 되었음. 백엔드와 프론트엔드가 하나로 합쳐져있을때는 origin 옵션에 URL 하나만 걸어두면 그만인데, 백엔드/프론트엔드 나눠놓은 상황에서는 프론트전용 URL(webOrigin)/백엔드전용 도메인(handleHost) 각각 분리를 해야했음. 그와 관련된 패치를 어제 했었던 것으로 기억한다.

변경사항이 있었다는걸 까먹은 상태에서, 로컬환경에서 원격 인스턴스에 Follow 액티비티가 왜 Unauthorized 에러가 뜨면서 전송이 되지 않았나했는데... 역시 이런 맥락이 있었던 것. 즉, handleHost(백엔드쪽 도메인)은 Tailscale에서 생성한 URL로 들어가는 반면, webOrigin은 localhost로 설정이 되어 있었기 때문에 서명하는 과정에서 오류가 발생한 것임. NODE_ENV 환경변수가 development 인 경우에만 webOrigin/handleHost를 같은값을 쓰는 걸로 임시방편으로 처리함. 관련 코드

4
5

액터/사용자만 나열하는 방식으로 러프하게 어드민 페이지 구현 완료. 배포하면 어떻게 될지 모르겠군. 개인적으로는 어드민 페이지는 아예 별개의 서비스로 분리가 되어있어야 한다고 보는 입장이라, 아예 별개의 패키지로 나눔 @cosmoslide/admin 같은 식으로

바이브코딩으로 뚝딱 만든 어드민 페이지
3

개발일지 251008

k8s로 배포할까 했는데, 다들 뜯어말리기도 했고 claude code로 바이브코딩한거 부채청산할 자신도 없어서 그냥 docker compose에다가 리버스프록시는 caddy로 물려서 올리는 중...... 근데, 라우터 설정하는 부분이 병목인데(집에서 세팅해야함) 당장은 못하는 관계로 다른 기능을 붙이는데 집중하고자 한다.

어드민 페이지랑 메일링 서비스 연동 게섯거라...

5

작업 내역

  • https://github.com/cosmoslide/cosmoslide/pull/45 PDF 업로드 기능이라도 구축은 해야할 것 같아서 진행함. 보통은 express라던가 등등 JS 기반의 웹서버 프레임워크에서는 파일시스템/S3/GCS 등의 스토리지에 파일을 업로드할때, 스토리지에 접근하는 과정 자체를 추상화하는 flydrive라는걸 쓰는데, flydrive는 NestJS에서 사용이 되지 않는 ESM-only 모듈이어서, 어떻게 해야 하나 하다가 Claude Code한테 AWS S3에 접근하는 것만 적당히 추상화해서 야크쉐이빙 해달라고 했더니 그냥 순식간에 되었다. 문서를 뜯어보고 구현해야하는 수고는 줄었고, aws sdk를 어떻게 활용하는지는 가성비있게 학습할 수 있는 기회가 되었다.

  • https://github.com/cosmoslide/cosmoslide/pull/46 프로필 화면에 Presentation 탭을 넣었고, 프레젠테이션 파일을 업로드하면 Create(Note) 액티비티가 발생되도록 처리했다. react-pdf 이용해서 커스텀 PDF 뷰어 적당히 끼워넣었다.

PDF 업로드 기능 가설 검증프레젠테이션을 위한 커스텀 PDF 뷰어프로필 화면에 Presentation 탭 넣었다.
4

개발하다가 느낀 뻘 생각

연합우주 서비스를 호스팅한다는 관점에서 봤을때,

  • 팔로잉을 한다 -> 외부 인스턴스에서 오는 인바운드 트래픽을 수시로 맞을 준비를 한다.
  • 팔로워를 받는다 -> 아웃바운드 트래픽을 와다다다 쏠 준비를 한다.

이런 관점으로 볼 수 있는 것 같다.

외부 연합우주 인스턴스에 큐가 적게 쌓이게 하고 싶다면, 팔로우를 가능하면 하지 않는게 맞다..... 좀 감이 잡히는 것 같음

2

요즘 (https://github.com/cosmoslide/cosmoslide) 개발하면서 들고 있는 생각....


대부분의 액티비티펍 소프트웨어 인스턴스는 멀쩡하게 365일 24시간 동일한 위치에서 운영이 되고 있다고 가정이 된다. 내가 글을 올리면, 나를 팔로우 중인 모든 사람들의 inbox에 내가 글을 올렸다(Create(Note))는 Activity가 전달이 되는데, 각자가 운영되고 있는 서버 인스턴스가 멀쩡히 살아있다면.... 딱히 문제가 되지는 않는다.

문제는, 게시글을 작성하는 시점에 팔로워 중 누군가의 인스턴스가 죽어있을때도 있다는 점이다. 그런 경우를 대비해서 exponential backoff를 쓰든 아무튼 fallback 알고리즘이 동작하긴 하는데, 서버가 살아나면 당연히 전달이야 잘 되긴 한다. 그런데, Activity 전달이 실패하는 일이 잦으면 어떤 액티비티펍 소프트웨어를 쓰던간에 retry를 하기 위해서 계속해서 Queue에 쌓이고, 최종적으로는 Queue에 쌓인 것 때문에 적지 않은 오버헤드가 있을 것 같은데 모더레이터의 입장에선 어느 정도까지 감안할 수 있는가? 라는 생각이 문득 들었다.

사실 내가 왜 이런 글을 쓰고 있냐면, 위에서도 언급했다시피, 로컬호스트에서 실제로 서비스를 (맥북이 켜져있을때만) 서빙하고 있고 그걸 Tailscale로 연결해서 터널링을 하고 있다. 즉, 맥북을 켜놓고 있으면 Create(Note) Activity가 정상적으로 잘 전달되고, 맥북이 꺼져있으면 Activity 전달이 안되고 있다. 실제로, 이런 맥락에서 지금 테스트 중인 두 개의 인스턴스가 있다. 이런 실험적인 시도를 하면서 이래도 되는게 맞나 싶은 생각도 들고는 있다. 맥북을 켜놓으면, retry되고 있는 것도 다 consume되긴 하겠지만.... 찝찝하긴 찝찝하다.

개발하는 입장이라고 선해를 할 수는 있어도, 비뚤어진 관점에서 해석하면 누군가는 어뷰징의 관점으로 해석할 수 있는 가능성이 적지는 않다고 생각하고 있다. 이런 경우엔 모더레이터되는 분들한테, 내가 이런 tailscale 도메인으로 서빙하고 있다고 통지라도 하는게 나으려나... 아니면, 내가 구매해놓은 도메인을 tailscale 도메인으로 CNAME 걸어놓고 "이런 도메인으로 서비스 걸어놓을 예정이니까 이 도메인만은 제발 차단하지 말아주십쇼 헤헤" 라고 해야하나... 아예 서버를 만드는거다보니까 이런 고려사항이 생기는 것 같다.


근데, 한 편으로는 이런 생각이 든다. 물리적인 서버의 위치를 옮길 가능성이 많은 환경(예를 들면, 전시 상황)이면 어떡하지? ActivityPub이 사실은 분산된 웹 환경을 위해 나온 프로토콜이긴 하지만, 분산된 웹 환경이라는게 물리적으로 각자 다른 위치에 오랫동안 배치가 되어 있는 서버 뿐만이 아니라 위치가 자주 바뀔 수 있는 서버도 연합의 대상으로 포함이 될 수 있다면? 어떤 공상과학 영화(ex. 터미네이터4)들을 보면, 저항군이 독자적인 라디오 기지국 같은거 만들고 위치도 매번 다른 곳으로 옮기고 주파수를 매번 다르게 설정하면서 소식전달하는 모습을 볼 수 있는데, 액티비티펍도 어떻게 보면 그걸 고려한 설계도 포함될 수 있지 않나... 그런 생각도 든다..

5

2025-09-07 오늘의 작업한 내용 메모

https://github.com/cosmoslide/cosmoslide/pull/14

게시글 작성 기능까지는 안 갔지만, 연합우주 네트워크를 통해서 Create(Note), Announce(Note) 등의 액티비티가 들어왔을때 그것이 타임라인 화면에 노출되게 하는 기능을 작업했다. Actor 정보를 가져오는 과정에서 어떤 Actor는 lookup 하는 과정에서 Timeout 에러 뜨고, 어떤 Actor는 401 Unauthorized 뜨고, 어떤 Actor는 Person이 아니었어서 게시글 가져오는건 실패했는데... 이건 지속적인 개밥먹기를 꾸준히 해봐야 제대로 개선이 될 것 같음.

3

2025-09-03 오늘의 작업한 내용 메모

https://github.com/cosmoslide/cosmoslide/pull/13

  • 이전 버전까지는 Cosmoslide 의 모든 계정은 public이고 팔로우 버튼을 누르면 바로 팔로우가 되는 로직으로 구현이 되어 있었음.
    • 즉, Follow 액티비티를 받으면 액티비티를 보낸 액터의 inbox에다가 바로 Accept(Follow) 액티비티를 보내는 구성
  • 이번에 작업한 내용은 각각의 계정을 private으로 변환할 수 있고, private 계정에 팔로우 버튼을 눌렀을때 바로 팔로우가 되는게 아니라 팔로우 요청으로 처리되도록 하는 작업이었음
    • 즉, Follow 액티비티를 받으면, manuallyAcceptsFollowers 옵션이 false인 경우에만 Accept(Follow) 액티비티를 보냄
  • 팔로우 요청 관리하는 화면 바이브코딩으로 적당히 빠르게 만들고..... 팔로우 요청을 수락하거나, 팔로우 요청을 거절하는 액션 자체는 서버 측 비즈니스 로직에서 처리한다기 보다는 가능하면 Federation에서 처리하도록 했음.
    • 즉, 팔로우 요청 수락버튼을 누르면 Accept(Follow) 액티비티가 전송되고, 팔로우 요청 거절 버튼을 누르면 Reject(Follow) 액티비티가 전송되는 방식

로컬 환경에 있는 서로 다른 두 액터끼리는 잘 되는걸 확인했는데, 서로 다른 서버의 액터끼리 잘 되는지는 좀 더 테스트가 필요함.

이번 주말까지는 게시글 작성하고 원격 서버 타임라인에 노출되는 것까지 어떻게 되긴 할 듯.

2