Scheduling is decharged of API Call Datacentering + charged of booking

This commit is contained in:
mr
2026-02-25 09:04:48 +01:00
parent c8b8955c4b
commit 29623244c4
10 changed files with 512 additions and 277 deletions

71
docs/seq_check.puml Normal file
View File

@@ -0,0 +1,71 @@
@startuml seq_check
title Flux CHECK Peer A Peer B via oc-discovery
skinparam sequenceMessageAlign center
skinparam sequence {
ArrowColor #333333
LifeLineBorderColor #888888
GroupBorderColor #777777
GroupBackgroundColor #FAFAFA
NoteBackgroundColor #FFFDE7
NoteBorderColor #CCAA00
BoxBorderColor #555555
}
skinparam ParticipantBackgroundColor #FFFFFF
box "Peer A" #EAF3FB
participant "oc-scheduler A" as SA
participant "oc-discovery A" as DA
end box
box "Peer B" #EAF9EE
participant "oc-discovery B" as DB
participant "oc-scheduler B" as SB
end box
participant "Client" as Client
'
== Alimentation continue du PlannerCache (fond permanent) ==
'
note over SA, SB
Déclenché par : démarrage de SB, booking local créé,
TTL planner expiré refreshSelfPlanner()
end note
SB -> DB : **NATS PUB** · PROPALGATION_EVENT\nPB_PLANNER { peer_id, schedule, capacities }
DB --> DA : **STREAM** · PropalgationMessage\n{ action: PB_PLANNER }
DA -> SA : **NATS SUB** · PROPALGATION_EVENT\n[ FromApp = "oc-discovery" ]
SA -> SA : storePlanner(PeerB.PeerID, planner)\n PlannerCache[PeerB.PeerID] = p
'
== Flux CHECK (POST /oc/:wfID/check) ==
'
Client -> SA : POST /oc/:wfID/check\n?as_possible=true&preemption=false
group Résolution du workflow
SA -> SA : workflow.LoadOne(wfID)
SA -> SA : collectBookingResources(wf)\n [ { peerID=B, resourceID, instanceID } ]
end
group Vérification locale contre le cache
SA -> SA : checkResourceAvailability()\nPlannerCache[PeerB.PeerID].Check(res, inst, start, end)
alt slot disponible
SA -> SA : available = true
else slot occupé
SA -> SA : findNextSlot(window=5h, pas=15min)\n next_slot
end
end
SA -> Client : **CheckResult**\n{ available, start, end, next_slot, warnings }
note over Client, SB
Aucun appel réseau pendant le check :
tout est résolu depuis le PlannerCache local de A.
oc-discovery n'intervient qu'en amont (fond continu).
end note
@enduml

95
docs/seq_schedule.puml Normal file
View File

@@ -0,0 +1,95 @@
@startuml seq_schedule
title Flux SCHEDULE Peer A Peer B via oc-discovery
skinparam sequenceMessageAlign center
skinparam sequence {
ArrowColor #333333
LifeLineBorderColor #888888
GroupBorderColor #777777
GroupBackgroundColor #FAFAFA
NoteBackgroundColor #FFFDE7
NoteBorderColor #CCAA00
BoxBorderColor #555555
}
skinparam ParticipantBackgroundColor #FFFFFF
participant "Client" as Client
box "Peer A" #EAF3FB
participant "oc-scheduler A" as SA
participant "oc-discovery A" as DA
end box
box "Peer B" #EAF9EE
participant "oc-discovery B" as DB
participant "oc-scheduler B" as SB
end box
'
Client -> SA : POST /oc/:wfID
'
group Planification synchrone (GetBuyAndBook)
SA -> SA : workflow.LoadOne(wfID)\nwf.Planify(start, end, instances, )\nexec.Buy() purchases [ DestPeerID = B ]\nexec.Book() bookings [ DestPeerID = B ]\n WorkflowExecution {\n BookingsState: { booking_id: false }\n PurchasesState: { purchase_id: false }\n }
end
'
group Propagation vers Peer B goroutines (errCh attend l'envoi NATS, pas la réception par B)
SA -> DA : **NATS PUB** · CREATE_RESOURCE\nPURCHASE_RESOURCE { DestPeerID=B, IsDraft=true }
note right of DA : oc-discovery A est le\nrécepteur systématique\ndes émissions NATS de SA
DA --> DB : **STREAM** · PropalgationMessage\n{ datatype: PURCHASE_RESOURCE }
DB -> SB : **NATS SUB** · CREATE_RESOURCE PURCHASE_RESOURCE
SA -> DA : **NATS PUB** · CREATE_RESOURCE\nBOOKING { DestPeerID=B, IsDraft=true }
DA --> DB : **STREAM** · PropalgationMessage\n{ datatype: BOOKING }
DB -> SB : **NATS SUB** · CREATE_RESOURCE BOOKING
end
'
group Peer B traite async (ListenNATS goroutine de SB)
SB -> SB : StoreOne(purchase, IsDraft=true)\nAfterFunc(10 min draftTimeout)
SB -> DB : **NATS PUB** · PROPALGATION_EVENT\nConsiders { DataType:PURCHASE_RESOURCE,\n id=purchase_id, execution_id }
note right of DB : SB émet sur son NATS local\nDB (oc-discovery B) reçoit
DB --> DA : **STREAM** · PropalgationMessage\n{ action: Considers, DataType: PURCHASE_RESOURCE }
DA -> SA : **NATS SUB** · PROPALGATION_EVENT\n[ FromApp = "oc-discovery" ]
SA -> SA : updateExecutionState()\nPurchasesState[ purchase_id ] = true
SB -> SB : PlannerCache[self].Check(slot) \nStoreOne(booking, IsDraft=true)\nAfterFunc(10 min draftTimeout)\nrefreshSelfPlanner()
SB -> DB : **NATS PUB** · PROPALGATION_EVENT\nPB_PLANNER { peer_id, schedule, capacities }
DB --> DA : **STREAM** · PropalgationMessage\n{ action: PB_PLANNER }
DA -> SA : **NATS SUB** · PROPALGATION_EVENT\n[ FromApp = "oc-discovery" ]
SA -> SA : storePlanner(PeerB.PeerID, p)
SB -> DB : **NATS PUB** · PROPALGATION_EVENT\nConsiders { DataType:BOOKING,\n id=booking_id, execution_id }
DB --> DA : **STREAM** · PropalgationMessage\n{ action: Considers, DataType: BOOKING }
DA -> SA : **NATS SUB** · PROPALGATION_EVENT\n[ FromApp = "oc-discovery" ]
SA -> SA : updateExecutionState()\nBookingsState[ booking_id ] = true\n tous true State = SCHEDULED (DB)
end
'
group Schedules() finalise synchrone (concurrent avec )
SA -> SA : GenerateOrder(purchases, bookings)\nexec.PurgeDraft()\nexec.StoreDraftDefault() State=SCHEDULED, IsDraft=false\nGenericStoreOne(exec)
SA -> DA : **NATS PUB** · PROPALGATION_EVENT [goroutine]\nConsiders { DataType:WORKFLOW_EXECUTION,\n execution, peer_ids:[ PeerB ] }
note right of DA : oc-discovery A reçoit\net STREAM vers tous les\npairs listés dans peer_ids
DA --> DB : **STREAM** · PropalgationMessage\n{ action: Considers, DataType: WORKFLOW_EXECUTION }
DB -> SB : **NATS SUB** · PROPALGATION_EVENT\n[ FromApp = "oc-discovery" ]
SB -> SB : confirmExecutionDrafts()\nconfirmResource(booking_id)\n Booking.IsDraft=false, State=SCHEDULED\nconfirmResource(purchase_id)\n Purchase.IsDraft=false
SA -> Client : **{WorkflowSchedule, Workflow, Executions}**
end
note over SA, SB
et sont concurrents.
En pratique : GenerateOrder + écritures DB côté A
laissent le temps à B de recevoir et stocker ses drafts
avant que A émette le Considers/WORKFLOW_EXECUTION.
end note
@enduml