- ControlPlane 라우터에 워커/에이전트 구독 채널을 추가한다 - ProtoSocket 기반 실시간 양방향 채널( dispatcher, envelope, server)을 구현한다 - Forgejo push 이벤트를 provider 어댑터로 처리하도록 연동한다 - PostgreSQL 스토리지 백엔드를 분리하여 postgres.go로 신설한다 - Git engine command에 diff/checkout/merge 연쇄 연산을 추가한다 - 런타임 모델에 agentSession, runtimeChannel 스키마를 추가한다 - 데이터베이스 마이그레이션에 agent_session, runtime_channel, lease 테이블을 추가한다 - agent-contract에 Forgejo branch events 계약 문서를 작성한다 - 로드맵 마일스톤과 아카이브 작업을 갱신한다
88 lines
1.8 KiB
Go
88 lines
1.8 KiB
Go
package protosocket
|
|
|
|
import "strings"
|
|
|
|
type EventSubscriber interface {
|
|
Subscribe(connectionID string, subscription EventSubscription) EventSubscription
|
|
}
|
|
|
|
type EventSubscription struct {
|
|
Events []string
|
|
RepoID string
|
|
Branch string
|
|
}
|
|
|
|
func (s EventSubscription) Normalized() EventSubscription {
|
|
events := make([]string, 0, len(s.Events))
|
|
seen := make(map[string]struct{}, len(s.Events))
|
|
for _, event := range s.Events {
|
|
event = strings.TrimSpace(event)
|
|
if event == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[event]; ok {
|
|
continue
|
|
}
|
|
seen[event] = struct{}{}
|
|
events = append(events, event)
|
|
}
|
|
return EventSubscription{
|
|
Events: events,
|
|
RepoID: strings.TrimSpace(s.RepoID),
|
|
Branch: strings.TrimSpace(s.Branch),
|
|
}
|
|
}
|
|
|
|
func (s EventSubscription) Allows(env Envelope) bool {
|
|
s = s.Normalized()
|
|
if env.Type != "event" {
|
|
return false
|
|
}
|
|
if !s.allowsEventName(env.Action, stringPayload(env.Payload, "type")) {
|
|
return false
|
|
}
|
|
if s.RepoID != "" && s.RepoID != stringPayload(env.Payload, "repo_id") {
|
|
return false
|
|
}
|
|
if s.Branch != "" && s.Branch != stringPayload(env.Payload, "branch") {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (s EventSubscription) Payload() map[string]any {
|
|
s = s.Normalized()
|
|
events := make([]any, 0, len(s.Events))
|
|
for _, event := range s.Events {
|
|
events = append(events, event)
|
|
}
|
|
return map[string]any{
|
|
"events": events,
|
|
"repo_id": s.RepoID,
|
|
"branch": s.Branch,
|
|
}
|
|
}
|
|
|
|
func (s EventSubscription) allowsEventName(action, payloadType string) bool {
|
|
if len(s.Events) == 0 {
|
|
return true
|
|
}
|
|
for _, event := range s.Events {
|
|
if event == "*" || event == action || event == payloadType {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func stringPayload(payload map[string]any, key string) string {
|
|
value, ok := payload[key]
|
|
if !ok {
|
|
return ""
|
|
}
|
|
text, ok := value.(string)
|
|
if !ok {
|
|
return ""
|
|
}
|
|
return strings.TrimSpace(text)
|
|
}
|