feat(strategy-state): persist instance-scoped slot maps
This commit is contained in:
@@ -74,11 +74,14 @@
|
||||
```
|
||||
{ "filter": "all" | "inactive" | "pending" | "holding" | "error", # default "all"
|
||||
"spy": true | false, # default false; true = watchdog 갱신 안 함(운영자 조회)
|
||||
"strategy": str # optional (REQ-116 BAT-055) — exact-match on strategy_name
|
||||
"strategy": str, # optional (REQ-116 BAT-055) — exact-match on strategy_name
|
||||
"strategy_instance_id": str # required non-empty string when spy=false; ignored for spy=true filtering
|
||||
}
|
||||
```
|
||||
- `filter`: 서버 측 슬롯 status 필터. `"inactive"` 는 buyable 슬롯(universe에 바인딩된 매수 가능 슬롯). 미인식 값은 `"all"` 로 처리.
|
||||
- `spy=true`: 응답에 포함된 holding 슬롯의 워치독 `last_seen_at` 을 갱신하지 않는다(운영자 CLI 조회가 전략 생존 신호로 오인되지 않도록 — REQ-034 CHG-01).
|
||||
- `spy=false`: `strategy_instance_id`는 required non-empty string이다. 누락·비문자열·빈 값은 `{slots:[], available_slots:null, degraded:false, reason:"bad_request:strategy_instance_id", message:"strategy_instance_id must be a non-empty string"}`를 반환하며 watchdog을 갱신하지 않는다.
|
||||
- strategy-state visibility: `spy=false`는 exact requested entry 하나를 `strategy_state: {version,data,updated_at}`로만 반환하고 missing entry는 생략한다. `spy=true`는 supplied ID와 무관하게 complete `{strategy_instance_id: {version,data,updated_at}}` map을 반환한다.
|
||||
- `strategy` (REQ-116 additive): 지정 시 `strategy_name == strategy` 인 슬롯 행만 반환. 대소문자 exact-match. 미지정 시 기존과 완전 동일. `filter` 와 AND 조합. 매칭 없으면 `slots=[]`(에러 없음). `available_slots` 는 strategy 필터와 무관하게 인스턴스 전체 기준으로 계산(REQ-073 AC-6 불변).
|
||||
|
||||
코어가 reply-to 큐로 보내는 응답 payload:
|
||||
@@ -524,21 +527,21 @@ get_current_price(symbol: str, market: str = "J") -> Optional[Decimal]
|
||||
- pika BlockingConnection 은 thread-safe 가 아니므로 consumer/publisher 마다 자기 connection/channel 을 가져야 한다.
|
||||
- 토폴로지 선언은 멱등하지만 attribute(durable, args) 가 기존 큐와 다르면 RabbitMQ 가 PRECONDITION_FAILED 로 거부 → batch 마이그레이션 시 큐 재선언 절차 필요.
|
||||
|
||||
## Interface: `trex.slots.strategy_state.set` RPC (BAT-042 / dcy-028, REQ-080)
|
||||
## Interface: `trex.slots.strategy_state.set` RPC (REQ-0009)
|
||||
|
||||
- Type: external-service (strategy daemon ↔ core write RPC)
|
||||
- Consumers / Producers: 전략 데몬(produce) ↔ core 핸들러(consume). per-instance 큐(`{base}.{instance_key}`), direct reply-to, JSON.
|
||||
- Purpose: 슬롯의 opaque strategy-state 를 occupancy_seq+version CAS 로 write. read 는 `trex.slots.req` 에 piggyback(별도 RPC 아님).
|
||||
- Purpose: 슬롯별 opaque strategy-instance state entry를 version CAS로 write. read는 `trex.slots.req`에 piggyback(별도 RPC 아님).
|
||||
|
||||
### Inputs
|
||||
- `{slot_id, strategy_id, expected_version:int, expected_occupancy_seq:int, data:str}`. `correlation_id = "{slot_id}:{strategy_id}:{expected_version}"`(멱등), delivery persistent. `data` 는 opaque UTF-8(core 무해석), byte size cap(기본 4KB ceiling, 운영 권장 1~2KB).
|
||||
- `{slot_id, strategy_instance_id, expected_version:int, data:str}`. `strategy_instance_id`는 required non-empty string이며 `correlation_id`는 저장 멱등성 key가 아니다. `data`는 opaque UTF-8(core 무해석), byte size cap(기본 4KB ceiling, 운영 권장 1~2KB).
|
||||
|
||||
### Outputs / Outcomes
|
||||
- 성공: `{ok:true, slot_id, strategy_id, version:<new>}`.
|
||||
- 실패 reason 전체 집합: `occupancy_changed`(+`occupancy_seq`) / `version_conflict`(+`version`) / `slot_inactive` / `state_too_large` / `bad_request:<detail>`. 소비자는 미인식 reason 에 fail-closed.
|
||||
- 성공: `{ok:true, slot_id, strategy_instance_id, version:<new>}`.
|
||||
- 실패 reason 전체 집합: `version_conflict`(+`version`) / `slot_inactive` / `state_too_large` / `bad_request:<detail>`. 소비자는 미인식 reason에 fail-closed.
|
||||
|
||||
### Compatibility Rules
|
||||
- read 표면(`trex.slots.req`)의 각 슬롯 행에 additive 로 `occupancy_seq`(int)와, 보유 시 `strategy_state` 맵(`{<strategy_id>:{version,data,updated_at}}`)이 실린다(REQ-073/074 CHG). 기존 소비자는 unknown 필드 무시로 하위호환. `strategy_state` 는 strategy_* reasoning 필드(strategy_id 등, REQ-074 AC-5 제외 대상)와 구분되는 opaque 상태 맵이다.
|
||||
- slot strategy-state는 occupancy와 독립된 slot-scoped `data[strategy_instance_id] = {version,data,updated_at}` map이다. close/reopen은 entry를 삭제하거나 version을 초기화하지 않는다. Entry에는 `strategy_id`나 `occupancy_seq` metadata가 없으며, Slot 자체의 `occupancy_seq` semantics는 별도로 유지된다.
|
||||
|
||||
## Shared Constraints
|
||||
|
||||
|
||||
Reference in New Issue
Block a user