@zlink-systems/framework 0.30.1 → 0.30.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Common/ZLinkEncodedPayload.d.ts +6 -0
  3. package/dist/contracts/Common/ZLinkEncodedPayload.js +18 -3
  4. package/dist/contracts/Common/encoded-payload-storage.d.ts +1 -1
  5. package/dist/contracts/Common/encoded-payload-storage.js +5 -2
  6. package/dist/contracts/Configuration/Builders.d.ts +1 -1
  7. package/dist/contracts/Configuration/RegistrationBuilderPolicy.d.ts +2 -1
  8. package/dist/contracts/Configuration/RegistrationBuilderPolicy.js +5 -1
  9. package/dist/contracts/Configuration/RegistrationBuilders.js +2 -2
  10. package/dist/contracts/Configuration/RegistrationTypes.d.ts +1 -0
  11. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +2 -2
  12. package/dist/contracts/Locations/Rows.d.ts +2 -0
  13. package/dist/contracts/Spots/Contracts.d.ts +4 -0
  14. package/dist/contracts/Spots/ZLinkSpot.d.ts +3 -3
  15. package/dist/runtime/abort.d.ts +5 -0
  16. package/dist/runtime/abort.js +10 -0
  17. package/dist/runtime/actors/actor-authority-publication.js +3 -2
  18. package/dist/runtime/actors/actor-client.d.ts +0 -1
  19. package/dist/runtime/actors/actor-client.js +38 -45
  20. package/dist/runtime/actors/actor-context.d.ts +2 -0
  21. package/dist/runtime/actors/actor-context.js +46 -9
  22. package/dist/runtime/actors/actor-handoff.d.ts +7 -3
  23. package/dist/runtime/actors/actor-handoff.js +212 -88
  24. package/dist/runtime/actors/actor-join-relocation.d.ts +2 -0
  25. package/dist/runtime/actors/actor-local-native-join.js +4 -0
  26. package/dist/runtime/actors/actor-mailbox.js +27 -1
  27. package/dist/runtime/actors/actor-remote-joiner.js +3 -1
  28. package/dist/runtime/actors/actor-reply.d.ts +4 -0
  29. package/dist/runtime/actors/actor-reply.js +29 -0
  30. package/dist/runtime/actors/actor-runtime-contracts.d.ts +2 -0
  31. package/dist/runtime/actors/actor-runtime-state.js +2 -20
  32. package/dist/runtime/actors/actor-source-transfer.d.ts +1 -17
  33. package/dist/runtime/actors/index.d.ts +6 -2
  34. package/dist/runtime/actors/index.js +37 -21
  35. package/dist/runtime/actors/session-disconnected-wire.d.ts +8 -0
  36. package/dist/runtime/actors/session-disconnected-wire.js +48 -0
  37. package/dist/runtime/admission.d.ts +9 -1
  38. package/dist/runtime/admission.js +55 -32
  39. package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +13 -0
  40. package/dist/runtime/application-jobs/application-job-queue-scope.js +27 -1
  41. package/dist/runtime/application-jobs/contracts.d.ts +2 -0
  42. package/dist/runtime/backend/contracts/index.d.ts +19 -3
  43. package/dist/runtime/backend/mesh-actor-session-node-adapter.js +2 -2
  44. package/dist/runtime/backend/mesh-completion-table.js +5 -0
  45. package/dist/runtime/backend/mesh-dispatch-pump.d.ts +26 -2
  46. package/dist/runtime/backend/mesh-dispatch-pump.js +193 -107
  47. package/dist/runtime/backend/node/node-raw-binding-port.js +90 -58
  48. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +33 -8
  49. package/dist/runtime/backend/node/node-raw-mesh-backend.js +142 -143
  50. package/dist/runtime/backend/node/node-socket-backend-adapter.d.ts +1 -1
  51. package/dist/runtime/backend/node/node-socket-backend-adapter.js +5 -5
  52. package/dist/runtime/channels/channel-clients.d.ts +1 -0
  53. package/dist/runtime/channels/channel-clients.js +20 -5
  54. package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +22 -3
  55. package/dist/runtime/channels/channel-dispatch-pipeline.js +103 -57
  56. package/dist/runtime/channels/channel-dispatchers.d.ts +3 -2
  57. package/dist/runtime/channels/channel-dispatchers.js +44 -37
  58. package/dist/runtime/channels/channel-envelope.d.ts +1 -0
  59. package/dist/runtime/channels/channel-envelope.js +74 -31
  60. package/dist/runtime/channels/channel-runtime-lifecycle.d.ts +4 -3
  61. package/dist/runtime/channels/channel-runtime-lifecycle.js +19 -24
  62. package/dist/runtime/channels/channel-runtime-manager.d.ts +3 -2
  63. package/dist/runtime/channels/channel-runtime-manager.js +4 -4
  64. package/dist/runtime/channels/channel-transports.d.ts +0 -1
  65. package/dist/runtime/channels/channel-transports.js +35 -33
  66. package/dist/runtime/channels/client-server-location-runtime.js +5 -4
  67. package/dist/runtime/channels/dispatch-error-reporter.d.ts +2 -1
  68. package/dist/runtime/channels/dispatch-error-reporter.js +2 -1
  69. package/dist/runtime/channels/fanout-location-runtime.d.ts +1 -1
  70. package/dist/runtime/channels/fanout-location-runtime.js +3 -3
  71. package/dist/runtime/diagnostics/flow-context.js +19 -7
  72. package/dist/runtime/diagnostics/index.js +4 -9
  73. package/dist/runtime/diagnostics/message-flow.d.ts +8 -0
  74. package/dist/runtime/diagnostics/message-flow.js +35 -5
  75. package/dist/runtime/diagnostics/runtime-metrics.d.ts +2 -2
  76. package/dist/runtime/diagnostics/runtime-metrics.js +10 -8
  77. package/dist/runtime/execution/index.d.ts +4 -2
  78. package/dist/runtime/execution/index.js +33 -10
  79. package/dist/runtime/execution/serial-execution-queue.d.ts +4 -0
  80. package/dist/runtime/execution/serial-execution-queue.js +21 -2
  81. package/dist/runtime/execution/state-lane.d.ts +2 -0
  82. package/dist/runtime/execution/state-lane.js +5 -0
  83. package/dist/runtime/foundation/operation-registry.d.ts +25 -1
  84. package/dist/runtime/foundation/operation-registry.js +86 -18
  85. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +39 -3
  86. package/dist/runtime/foundation/raw-service-mesh-runtime.js +151 -55
  87. package/dist/runtime/foundation/service-liveness-registry.d.ts +12 -1
  88. package/dist/runtime/foundation/service-liveness-registry.js +38 -0
  89. package/dist/runtime/foundation/service-mailbox.d.ts +7 -0
  90. package/dist/runtime/foundation/service-maintenance-runtime.js +1 -6
  91. package/dist/runtime/foundation/service-relocation-object-owner.d.ts +2 -3
  92. package/dist/runtime/foundation/service-relocation-object-owner.js +48 -35
  93. package/dist/runtime/foundation/service-relocation-runtime.js +7 -3
  94. package/dist/runtime/foundation/service-runtime-contracts.d.ts +8 -1
  95. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +2 -1
  96. package/dist/runtime/foundation/service-stateful-registry.d.ts +5 -4
  97. package/dist/runtime/foundation/service-stateful-registry.js +24 -26
  98. package/dist/runtime/foundation/service-stateful-runtime.d.ts +72 -6
  99. package/dist/runtime/foundation/service-stateful-runtime.js +444 -117
  100. package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +14 -1
  101. package/dist/runtime/foundation/service-stateful-wire-codec.js +48 -27
  102. package/dist/runtime/foundation/service-wire-binary-primitives.d.ts +6 -1
  103. package/dist/runtime/foundation/service-wire-binary-primitives.js +27 -11
  104. package/dist/runtime/foundation/service-wire-constants.generated.d.ts +1 -0
  105. package/dist/runtime/foundation/service-wire-constants.generated.js +1 -0
  106. package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +10 -0
  107. package/dist/runtime/foundation/service-wire-m6a-codec.js +166 -53
  108. package/dist/runtime/host/actor-packet-relay.d.ts +6 -4
  109. package/dist/runtime/host/actor-packet-relay.js +59 -72
  110. package/dist/runtime/host/actor-placement-coordinator.js +25 -8
  111. package/dist/runtime/host/actor-transfer-runtime.d.ts +7 -31
  112. package/dist/runtime/host/actor-transfer-runtime.js +85 -331
  113. package/dist/runtime/host/application-job-queue.d.ts +24 -3
  114. package/dist/runtime/host/application-job-queue.js +28 -41
  115. package/dist/runtime/host/index.d.ts +5 -1
  116. package/dist/runtime/host/index.js +171 -97
  117. package/dist/runtime/host/location-runtime-owner.js +2 -6
  118. package/dist/runtime/host/mesh-router-resolver.d.ts +4 -0
  119. package/dist/runtime/host/mesh-router-resolver.js +14 -6
  120. package/dist/runtime/host/remote-bound-session-relay.d.ts +2 -4
  121. package/dist/runtime/host/remote-bound-session-relay.js +71 -190
  122. package/dist/runtime/host/route-mesh-runtime.d.ts +2 -2
  123. package/dist/runtime/host/route-mesh-runtime.js +5 -3
  124. package/dist/runtime/host/runtime-shutdown.d.ts +1 -0
  125. package/dist/runtime/host/runtime-shutdown.js +3 -2
  126. package/dist/runtime/host/service-relocation-host-runtime.d.ts +17 -7
  127. package/dist/runtime/host/service-relocation-host-runtime.js +550 -367
  128. package/dist/runtime/host/spot-runtime-options-factory.js +15 -7
  129. package/dist/runtime/host/user-spot-creation-coordinator.js +33 -84
  130. package/dist/runtime/locations/auto-connect-loop.d.ts +2 -0
  131. package/dist/runtime/locations/auto-connect-loop.js +22 -14
  132. package/dist/runtime/locations/auto-connect-reconciler.js +0 -6
  133. package/dist/runtime/locations/auto-connect-types.d.ts +0 -1
  134. package/dist/runtime/locations/descriptor-publication.d.ts +4 -0
  135. package/dist/runtime/locations/descriptor-publication.js +11 -0
  136. package/dist/runtime/locations/domain-store-contract.d.ts +1 -0
  137. package/dist/runtime/locations/in-memory-authority-store.d.ts +7 -1
  138. package/dist/runtime/locations/in-memory-authority-store.js +56 -19
  139. package/dist/runtime/locations/in-memory-location-store.js +1 -10
  140. package/dist/runtime/locations/index.d.ts +1 -0
  141. package/dist/runtime/locations/index.js +1 -0
  142. package/dist/runtime/locations/lease-tracker.js +1 -6
  143. package/dist/runtime/locations/location-store-repository.d.ts +51 -1
  144. package/dist/runtime/locations/location-store-repository.js +363 -139
  145. package/dist/runtime/locations/relocation-blob.d.ts +18 -1
  146. package/dist/runtime/locations/relocation-blob.js +52 -1
  147. package/dist/runtime/locations/request-source-resolver.d.ts +37 -0
  148. package/dist/runtime/locations/request-source-resolver.js +80 -0
  149. package/dist/runtime/locations/resolvers.js +1 -1
  150. package/dist/runtime/locations/runtime.d.ts +6 -2
  151. package/dist/runtime/locations/runtime.js +37 -30
  152. package/dist/runtime/messaging/payload-codec.d.ts +7 -1
  153. package/dist/runtime/messaging/payload-codec.js +7 -6
  154. package/dist/runtime/messaging/request-result.js +29 -26
  155. package/dist/runtime/protocol/service_wire_codec.generated.d.ts +19 -1
  156. package/dist/runtime/protocol/service_wire_codec.generated.js +85 -0
  157. package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +7 -1
  158. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +23 -7
  159. package/dist/runtime/spots/formal-remote-actor-admission-registry.js +3 -2
  160. package/dist/runtime/spots/index.d.ts +18 -11
  161. package/dist/runtime/spots/index.js +234 -176
  162. package/dist/runtime/spots/spot-activation-registry.d.ts +4 -2
  163. package/dist/runtime/spots/spot-activation-registry.js +21 -11
  164. package/dist/runtime/spots/spot-activation-state.d.ts +1 -1
  165. package/dist/runtime/spots/spot-activation-state.js +7 -7
  166. package/dist/runtime/spots/spot-activation.d.ts +6 -3
  167. package/dist/runtime/spots/spot-activation.js +123 -44
  168. package/dist/runtime/spots/spot-actor-admission-coordinator.d.ts +1 -0
  169. package/dist/runtime/spots/spot-actor-admission-coordinator.js +13 -22
  170. package/dist/runtime/spots/spot-actor-membership.d.ts +0 -1
  171. package/dist/runtime/spots/spot-actor-membership.js +0 -8
  172. package/dist/runtime/spots/spot-actor-packet-dispatch.js +33 -8
  173. package/dist/runtime/spots/spot-actor-packet-drain.js +5 -33
  174. package/dist/runtime/spots/spot-entry-activation.d.ts +2 -0
  175. package/dist/runtime/spots/spot-entry-activation.js +14 -9
  176. package/dist/runtime/spots/spot-handler-registry.d.ts +4 -3
  177. package/dist/runtime/spots/spot-handler-registry.js +6 -2
  178. package/dist/runtime/spots/spot-manager-internal-contracts.d.ts +2 -2
  179. package/dist/runtime/spots/spot-manager-public.js +2 -2
  180. package/dist/runtime/spots/spot-node-autoconnect.d.ts +2 -1
  181. package/dist/runtime/spots/spot-node-autoconnect.js +18 -39
  182. package/dist/runtime/spots/spot-node-runtime-manager.d.ts +19 -2
  183. package/dist/runtime/spots/spot-node-runtime-manager.js +115 -50
  184. package/dist/runtime/spots/spot-outbound.js +3 -3
  185. package/dist/runtime/spots/spot-remote-codec.js +5 -1
  186. package/dist/runtime/spots/spot-runtime-ports.d.ts +0 -1
  187. package/dist/runtime/spots/spot-serial-executor.d.ts +10 -0
  188. package/dist/runtime/spots/spot-serial-executor.js +61 -8
  189. package/dist/runtime/spots/spot-serial-turn-executor.js +19 -2
  190. package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
  191. package/dist/runtime/spots/spot-timer.d.ts +57 -5
  192. package/dist/runtime/spots/spot-timer.js +287 -103
  193. package/dist/runtime/streams/actor-session-binding-registry.d.ts +42 -11
  194. package/dist/runtime/streams/actor-session-binding-registry.js +165 -48
  195. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +8 -4
  196. package/dist/runtime/streams/bound-actor-relay-sender.d.ts +2 -1
  197. package/dist/runtime/streams/bound-actor-relay-sender.js +15 -8
  198. package/dist/runtime/streams/bound-session-service.d.ts +1 -1
  199. package/dist/runtime/streams/bound-session-service.js +6 -11
  200. package/dist/runtime/streams/index.d.ts +3 -2
  201. package/dist/runtime/streams/index.js +6 -4
  202. package/dist/runtime/streams/managed-stream.js +3 -2
  203. package/dist/runtime/streams/native-fallback-bound-session.js +8 -73
  204. package/dist/runtime/streams/session-actor-coordinator.d.ts +2 -8
  205. package/dist/runtime/streams/session-actor-coordinator.js +15 -32
  206. package/dist/runtime/streams/stream-binding-runtime-ports.d.ts +3 -10
  207. package/dist/runtime/streams/stream-session-runtime.js +1 -4
  208. package/dist/runtime/workers/index.js +1 -1
  209. package/package.json +3 -3
  210. package/src/contracts/Common/ZLinkEncodedPayload.ts +24 -4
  211. package/src/contracts/Common/encoded-payload-storage.ts +6 -3
  212. package/src/contracts/Configuration/Builders.ts +4 -1
  213. package/src/contracts/Configuration/RegistrationBuilderPolicy.ts +7 -2
  214. package/src/contracts/Configuration/RegistrationBuilders.ts +6 -2
  215. package/src/contracts/Configuration/RegistrationTypes.ts +1 -0
  216. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +2 -1
  217. package/src/contracts/Locations/Rows.ts +2 -0
  218. package/src/contracts/Spots/Contracts.ts +8 -0
  219. package/src/contracts/Spots/ZLinkSpot.ts +3 -3
  220. package/src/runtime/abort.ts +12 -0
  221. package/src/runtime/actors/actor-authority-publication.ts +3 -2
  222. package/src/runtime/actors/actor-client.ts +61 -70
  223. package/src/runtime/actors/actor-context.ts +49 -9
  224. package/src/runtime/actors/actor-handoff.ts +282 -106
  225. package/src/runtime/actors/actor-join-relocation.ts +2 -0
  226. package/src/runtime/actors/actor-local-native-join.ts +4 -0
  227. package/src/runtime/actors/actor-mailbox.ts +40 -2
  228. package/src/runtime/actors/actor-remote-joiner.ts +6 -1
  229. package/src/runtime/actors/actor-reply.ts +42 -0
  230. package/src/runtime/actors/actor-runtime-contracts.ts +2 -0
  231. package/src/runtime/actors/actor-runtime-state.ts +2 -20
  232. package/src/runtime/actors/actor-source-transfer.ts +1 -34
  233. package/src/runtime/actors/index.ts +41 -27
  234. package/src/runtime/actors/session-disconnected-wire.ts +66 -0
  235. package/src/runtime/admission.ts +69 -34
  236. package/src/runtime/application-jobs/application-job-queue-scope.ts +33 -1
  237. package/src/runtime/application-jobs/contracts.ts +2 -0
  238. package/src/runtime/backend/contracts/index.ts +39 -4
  239. package/src/runtime/backend/mesh-actor-session-node-adapter.ts +5 -3
  240. package/src/runtime/backend/mesh-completion-table.ts +4 -0
  241. package/src/runtime/backend/mesh-dispatch-pump.ts +223 -124
  242. package/src/runtime/backend/node/node-raw-binding-port.ts +106 -70
  243. package/src/runtime/backend/node/node-raw-mesh-backend.ts +221 -170
  244. package/src/runtime/backend/node/node-socket-backend-adapter.ts +5 -5
  245. package/src/runtime/channels/channel-clients.ts +49 -24
  246. package/src/runtime/channels/channel-dispatch-pipeline.ts +173 -124
  247. package/src/runtime/channels/channel-dispatchers.ts +116 -72
  248. package/src/runtime/channels/channel-envelope.ts +105 -36
  249. package/src/runtime/channels/channel-runtime-lifecycle.ts +13 -13
  250. package/src/runtime/channels/channel-runtime-manager.ts +12 -5
  251. package/src/runtime/channels/channel-transports.ts +49 -58
  252. package/src/runtime/channels/client-server-location-runtime.ts +11 -10
  253. package/src/runtime/channels/dispatch-error-reporter.ts +4 -2
  254. package/src/runtime/channels/fanout-location-runtime.ts +17 -9
  255. package/src/runtime/diagnostics/flow-context.ts +20 -7
  256. package/src/runtime/diagnostics/index.ts +1 -7
  257. package/src/runtime/diagnostics/message-flow.ts +47 -9
  258. package/src/runtime/diagnostics/runtime-metrics.ts +12 -10
  259. package/src/runtime/execution/index.ts +40 -14
  260. package/src/runtime/execution/serial-execution-queue.ts +31 -4
  261. package/src/runtime/execution/state-lane.ts +7 -0
  262. package/src/runtime/foundation/operation-registry.ts +98 -20
  263. package/src/runtime/foundation/raw-service-mesh-runtime.ts +244 -67
  264. package/src/runtime/foundation/service-liveness-registry.ts +39 -0
  265. package/src/runtime/foundation/service-mailbox.ts +8 -0
  266. package/src/runtime/foundation/service-maintenance-runtime.ts +1 -8
  267. package/src/runtime/foundation/service-relocation-object-owner.ts +54 -37
  268. package/src/runtime/foundation/service-relocation-runtime.ts +7 -3
  269. package/src/runtime/foundation/service-runtime-contracts.ts +12 -1
  270. package/src/runtime/foundation/service-session-binding-ingress-port.ts +2 -1
  271. package/src/runtime/foundation/service-stateful-registry.ts +38 -35
  272. package/src/runtime/foundation/service-stateful-runtime.ts +667 -152
  273. package/src/runtime/foundation/service-stateful-wire-codec.ts +49 -11
  274. package/src/runtime/foundation/service-wire-binary-primitives.ts +35 -12
  275. package/src/runtime/foundation/service-wire-constants.generated.ts +1 -0
  276. package/src/runtime/foundation/service-wire-m6a-codec.ts +187 -51
  277. package/src/runtime/host/actor-packet-relay.ts +113 -94
  278. package/src/runtime/host/actor-placement-coordinator.ts +31 -8
  279. package/src/runtime/host/actor-transfer-runtime.ts +104 -430
  280. package/src/runtime/host/application-job-queue.ts +29 -44
  281. package/src/runtime/host/index.ts +286 -129
  282. package/src/runtime/host/location-runtime-owner.ts +2 -6
  283. package/src/runtime/host/mesh-router-resolver.ts +13 -5
  284. package/src/runtime/host/remote-bound-session-relay.ts +86 -248
  285. package/src/runtime/host/route-mesh-runtime.ts +11 -5
  286. package/src/runtime/host/runtime-shutdown.ts +15 -4
  287. package/src/runtime/host/service-relocation-host-runtime.ts +784 -475
  288. package/src/runtime/host/spot-runtime-options-factory.ts +18 -7
  289. package/src/runtime/host/user-spot-creation-coordinator.ts +41 -100
  290. package/src/runtime/locations/auto-connect-loop.ts +22 -14
  291. package/src/runtime/locations/auto-connect-reconciler.ts +0 -6
  292. package/src/runtime/locations/auto-connect-types.ts +0 -1
  293. package/src/runtime/locations/descriptor-publication.ts +7 -0
  294. package/src/runtime/locations/domain-store-contract.ts +5 -0
  295. package/src/runtime/locations/in-memory-authority-store.ts +85 -23
  296. package/src/runtime/locations/in-memory-location-store.ts +1 -12
  297. package/src/runtime/locations/index.ts +1 -0
  298. package/src/runtime/locations/lease-tracker.ts +2 -9
  299. package/src/runtime/locations/location-store-repository.ts +628 -152
  300. package/src/runtime/locations/relocation-blob.ts +75 -1
  301. package/src/runtime/locations/request-source-resolver.ts +138 -0
  302. package/src/runtime/locations/resolvers.ts +2 -2
  303. package/src/runtime/locations/runtime.ts +70 -40
  304. package/src/runtime/messaging/payload-codec.ts +8 -11
  305. package/src/runtime/messaging/request-result.ts +33 -29
  306. package/src/runtime/protocol/service_wire_codec.generated.ts +87 -4
  307. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +13 -10
  308. package/src/runtime/spots/formal-remote-actor-admission-registry.ts +3 -2
  309. package/src/runtime/spots/index.ts +375 -281
  310. package/src/runtime/spots/spot-activation-registry.ts +25 -13
  311. package/src/runtime/spots/spot-activation-state.ts +12 -19
  312. package/src/runtime/spots/spot-activation.ts +170 -86
  313. package/src/runtime/spots/spot-actor-admission-coordinator.ts +25 -55
  314. package/src/runtime/spots/spot-actor-membership.ts +0 -15
  315. package/src/runtime/spots/spot-actor-packet-dispatch.ts +56 -11
  316. package/src/runtime/spots/spot-actor-packet-drain.ts +9 -52
  317. package/src/runtime/spots/spot-entry-activation.ts +24 -19
  318. package/src/runtime/spots/spot-handler-registry.ts +15 -4
  319. package/src/runtime/spots/spot-manager-internal-contracts.ts +2 -2
  320. package/src/runtime/spots/spot-manager-public.ts +2 -2
  321. package/src/runtime/spots/spot-node-autoconnect.ts +22 -45
  322. package/src/runtime/spots/spot-node-runtime-manager.ts +197 -67
  323. package/src/runtime/spots/spot-outbound.ts +3 -3
  324. package/src/runtime/spots/spot-remote-codec.ts +9 -2
  325. package/src/runtime/spots/spot-runtime-ports.ts +0 -1
  326. package/src/runtime/spots/spot-serial-executor.ts +97 -25
  327. package/src/runtime/spots/spot-serial-turn-executor.ts +22 -3
  328. package/src/runtime/spots/spot-subscription-dispatch.ts +1 -1
  329. package/src/runtime/spots/spot-timer.ts +413 -157
  330. package/src/runtime/streams/actor-session-binding-registry.ts +236 -64
  331. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +16 -8
  332. package/src/runtime/streams/bound-actor-relay-sender.ts +23 -9
  333. package/src/runtime/streams/bound-session-service.ts +7 -10
  334. package/src/runtime/streams/index.ts +12 -6
  335. package/src/runtime/streams/managed-stream.ts +4 -2
  336. package/src/runtime/streams/native-fallback-bound-session.ts +14 -103
  337. package/src/runtime/streams/session-actor-coordinator.ts +39 -88
  338. package/src/runtime/streams/stream-binding-runtime-ports.ts +3 -9
  339. package/src/runtime/streams/stream-session-runtime.ts +1 -5
  340. package/src/runtime/workers/index.ts +1 -1
@@ -15,7 +15,12 @@ import { submitToRequestResult } from '../messaging/submission-result';
15
15
  import { RequestResult, SubmitResult, isZLinkBackendResultError } from '../backend/runtime-values';
16
16
  import { enumWireRejectReason } from '../protocol/service_wire_codec.generated';
17
17
  import { SERVICE_WIRE_PREFIX_SIZE } from './service-wire-binary-primitives';
18
- import { OperationRegistry, type PendingOperation } from './operation-registry';
18
+ import {
19
+ OperationRegistry,
20
+ OperationTimeoutError,
21
+ type OperationObserver,
22
+ type PendingOperation
23
+ } from './operation-registry';
19
24
  import { ServiceLivenessRegistry, type ServiceLivenessTick } from './service-liveness-registry';
20
25
  import { ServiceMailbox, type ServiceMailboxRecord } from './service-mailbox';
21
26
  import {
@@ -68,6 +73,19 @@ export interface RawServiceRequestResult {
68
73
  readonly payload?: ServiceApplicationPayload;
69
74
  }
70
75
 
76
+ /** Receives observed request terminals; the context is the caller's operation kind. */
77
+ export type RawServiceRequestObserver = OperationObserver<RawServiceRequestResult, number>;
78
+
79
+ /**
80
+ * A registered request. An observed remote request has no Promise; its
81
+ * terminal reaches the observer. Local and Promise-contract requests carry
82
+ * the Promise.
83
+ */
84
+ export interface RawServiceObservedRequest {
85
+ readonly id: bigint;
86
+ readonly promise?: Promise<RawServiceRequestResult>;
87
+ }
88
+
71
89
  type RawServiceChannelTargetSelection =
72
90
  | { readonly kind: 'selected'; readonly peer: AdmittedServicePeer }
73
91
  | {
@@ -85,6 +103,8 @@ type RawServiceChannelTargetSelection =
85
103
  type ServiceApplicationPayloadInput = ServiceApplicationPayload | Buffer;
86
104
 
87
105
  export interface RawServiceIngressRecord {
106
+ /** Source identity recorded once by the first accepting owner (Location runtime §9.3). */
107
+ requestSource?: import('../locations/request-source-resolver').ZLinkRequestSourceFence;
88
108
  readonly onAdmitted?: () => void;
89
109
  readonly command: number;
90
110
  readonly flags: number;
@@ -160,7 +180,7 @@ export class RawServiceMeshRuntime {
160
180
  readonly mailbox: ServiceMailbox;
161
181
  readonly liveness: ServiceLivenessRegistry;
162
182
 
163
- private readonly operations: OperationRegistry<RawServiceRequestResult>;
183
+ private readonly operations: OperationRegistry<RawServiceRequestResult, number>;
164
184
  private readonly expectedPeers = new Map<
165
185
  string,
166
186
  {
@@ -339,10 +359,12 @@ export class RawServiceMeshRuntime {
339
359
  if (router.disconnectRid !== undefined) {
340
360
  router.disconnectRid(nodeRoutingId);
341
361
  } else {
342
- router.disconnect(endpoint);
362
+ try {
363
+ router.disconnect(endpoint);
364
+ } catch (error) {
365
+ if (!isAlreadyDisconnectedError(error)) throw error;
366
+ }
343
367
  }
344
- } catch (error) {
345
- if (!isAlreadyDisconnectedError(error)) throw error;
346
368
  } finally {
347
369
  if (current !== undefined) this.removePeer(current);
348
370
  this.topology.forgetNotRequired(nodeRoutingId);
@@ -399,6 +421,35 @@ export class RawServiceMeshRuntime {
399
421
  };
400
422
  }
401
423
 
424
+ async waitForPeerRoute(
425
+ nodeRoutingId: string,
426
+ lifecycleGeneration: bigint,
427
+ deadlineUnixMs: bigint,
428
+ signal?: AbortSignal
429
+ ): Promise<void> {
430
+ const remaining = deadlineUnixMs - BigInt(Date.now());
431
+ if (remaining <= 0n) throw new OperationTimeoutError(0n);
432
+ const pending = this.operations.register(Number(remaining));
433
+ const check = () => {
434
+ if (this.isPeerRouteReady(nodeRoutingId, lifecycleGeneration)) {
435
+ this.operations.complete(pending.id, { terminalResult: RequestResult.Ok, failureCode: 0 });
436
+ }
437
+ };
438
+ const unsubscribe = this.observePeerRouteChanged((rid) => {
439
+ if (rid === nodeRoutingId) check();
440
+ });
441
+ const abort = () => this.operations.fail(pending.id, signal?.reason);
442
+ signal?.addEventListener('abort', abort, { once: true });
443
+ try {
444
+ if (signal?.aborted === true) abort();
445
+ else check();
446
+ await pending.promise;
447
+ } finally {
448
+ unsubscribe();
449
+ signal?.removeEventListener('abort', abort);
450
+ }
451
+ }
452
+
402
453
  get requestStopSignal(): AbortSignal {
403
454
  return this.applicationJobStop.signal;
404
455
  }
@@ -426,38 +477,39 @@ export class RawServiceMeshRuntime {
426
477
  for (const listener of this.peerConnectionIntentRemoved) listener(nodeRoutingId);
427
478
  }
428
479
 
429
- announcePeer(nodeRoutingId: string): Promise<boolean> {
480
+ announcePeer(nodeRoutingId: string): boolean {
481
+ if (this.closed) return false;
430
482
  const generation = this.selectedRoutes.get(nodeRoutingId);
431
- if (generation === undefined) return Promise.resolve(false);
432
- const current = () => {
433
- const admission = this.topology.routeAdmission(nodeRoutingId);
434
- return (
435
- this.selectedRoutes.get(nodeRoutingId) === generation &&
436
- !(
437
- admission?.connectionId === routeConnectionId(generation) &&
438
- admission.remoteAdmitReceived === true
439
- ) &&
440
- this.peerAdmissionSealed?.() !== true
441
- );
442
- };
483
+ if (generation === undefined) return false;
443
484
  const key = controlSendKey(nodeRoutingId, M6aServiceWireCommand.hello);
444
- if (!current()) {
485
+ if (!this.isPeerAnnouncementCurrent(nodeRoutingId, generation)) {
445
486
  this.controlSends.delete(key);
446
- return Promise.resolve(false);
487
+ return false;
447
488
  }
489
+ const current = () => this.isPeerAnnouncementCurrent(nodeRoutingId, generation);
448
490
  const existing = this.controlSends.get(key);
449
491
  const hello =
450
492
  existing?.current?.() === true
451
493
  ? existing.hello!
452
494
  : encodeRouteMeshAdmission(M6aServiceWireCommand.hello, this.topology.localDescriptor());
453
- return Promise.resolve(
454
- this.startControlSend(
455
- nodeRoutingId,
456
- M6aServiceWireCommand.hello,
457
- () => this.submitControl(nodeRoutingId, [hello]),
458
- current,
459
- hello
460
- )
495
+ return this.startControlSend(
496
+ nodeRoutingId,
497
+ M6aServiceWireCommand.hello,
498
+ () => this.submitControl(nodeRoutingId, [hello]),
499
+ current,
500
+ hello
501
+ );
502
+ }
503
+
504
+ private isPeerAnnouncementCurrent(nodeRoutingId: string, generation: bigint): boolean {
505
+ const admission = this.topology.routeAdmission(nodeRoutingId);
506
+ return (
507
+ this.selectedRoutes.get(nodeRoutingId) === generation &&
508
+ !(
509
+ admission?.connectionId === routeConnectionId(generation) &&
510
+ admission.remoteAdmitReceived === true
511
+ ) &&
512
+ this.peerAdmissionSealed?.() !== true
461
513
  );
462
514
  }
463
515
 
@@ -562,8 +614,32 @@ export class RawServiceMeshRuntime {
562
614
  payload: ServiceApplicationPayloadInput,
563
615
  timeoutMs: number,
564
616
  onAdmitted?: () => void
565
- ): PendingOperation<RawServiceRequestResult> {
566
- return this.requestToTarget(targetNodeRoutingId, payload, timeoutMs, undefined, onAdmitted);
617
+ ): PendingOperation<RawServiceRequestResult>;
618
+ requestToNode(
619
+ targetNodeRoutingId: string,
620
+ payload: ServiceApplicationPayloadInput,
621
+ timeoutMs: number,
622
+ onAdmitted: (() => void) | undefined,
623
+ observer: RawServiceRequestObserver,
624
+ operationKind: number
625
+ ): RawServiceObservedRequest;
626
+ requestToNode(
627
+ targetNodeRoutingId: string,
628
+ payload: ServiceApplicationPayloadInput,
629
+ timeoutMs: number,
630
+ onAdmitted?: () => void,
631
+ observer?: RawServiceRequestObserver,
632
+ operationKind?: number
633
+ ): RawServiceObservedRequest {
634
+ return this.requestToTarget(
635
+ targetNodeRoutingId,
636
+ payload,
637
+ timeoutMs,
638
+ undefined,
639
+ onAdmitted,
640
+ observer,
641
+ operationKind
642
+ );
567
643
  }
568
644
 
569
645
  requestToChannel(
@@ -571,11 +647,27 @@ export class RawServiceMeshRuntime {
571
647
  payload: ServiceApplicationPayloadInput,
572
648
  timeoutMs: number,
573
649
  onAdmitted?: () => void
574
- ): PendingOperation<RawServiceRequestResult> {
650
+ ): PendingOperation<RawServiceRequestResult>;
651
+ requestToChannel(
652
+ channelName: string,
653
+ payload: ServiceApplicationPayloadInput,
654
+ timeoutMs: number,
655
+ onAdmitted: (() => void) | undefined,
656
+ observer: RawServiceRequestObserver,
657
+ operationKind: number
658
+ ): RawServiceObservedRequest;
659
+ requestToChannel(
660
+ channelName: string,
661
+ payload: ServiceApplicationPayloadInput,
662
+ timeoutMs: number,
663
+ onAdmitted?: () => void,
664
+ observer?: RawServiceRequestObserver,
665
+ operationKind?: number
666
+ ): RawServiceObservedRequest {
575
667
  const selection = this.selectChannelTarget(channelName);
576
668
  if (selection.kind !== 'selected') {
577
- const pending = this.operations.register(timeoutMs);
578
- this.operations.complete(pending.id, selection.requestResult);
669
+ const pending = this.registerRequest(timeoutMs, observer, operationKind);
670
+ this.completeRequest(pending, selection.requestResult);
579
671
  return pending;
580
672
  }
581
673
  return this.requestToTarget(
@@ -583,10 +675,45 @@ export class RawServiceMeshRuntime {
583
675
  payload,
584
676
  timeoutMs,
585
677
  channelName,
586
- onAdmitted
678
+ onAdmitted,
679
+ observer,
680
+ operationKind
587
681
  );
588
682
  }
589
683
 
684
+ /**
685
+ * One pending entry per request: an observed request reports its terminal
686
+ * to the caller's observer; any other request keeps the Promise contract.
687
+ */
688
+ private registerRequest(
689
+ timeoutMs: number,
690
+ observer: RawServiceRequestObserver | undefined,
691
+ operationKind: number | undefined
692
+ ): RawServiceObservedRequest {
693
+ return observer === undefined
694
+ ? this.operations.register(timeoutMs)
695
+ : { id: this.operations.registerObserved(timeoutMs, observer, operationKind) };
696
+ }
697
+
698
+ /**
699
+ * An observed caller learns the operation id only when the request call
700
+ * returns, so a terminal decided inside that call is delivered after it.
701
+ */
702
+ private completeRequest(
703
+ pending: RawServiceObservedRequest,
704
+ result: RawServiceRequestResult
705
+ ): void {
706
+ if (pending.promise === undefined)
707
+ queueMicrotask(() => this.operations.complete(pending.id, result));
708
+ else this.operations.complete(pending.id, result);
709
+ }
710
+
711
+ private failRequest(pending: RawServiceObservedRequest, error: unknown): void {
712
+ if (pending.promise === undefined)
713
+ queueMicrotask(() => this.operations.fail(pending.id, error));
714
+ else this.operations.fail(pending.id, error);
715
+ }
716
+
590
717
  private selectChannelTarget(channelName: string): RawServiceChannelTargetSelection {
591
718
  const selected = this.topology.selectChannel(channelName, (peer) =>
592
719
  this.isPeerRouteReady(peer.descriptor.nodeRoutingId)
@@ -1043,6 +1170,7 @@ export class RawServiceMeshRuntime {
1043
1170
  ]);
1044
1171
  } else if (header.command === M6aServiceWireCommand.admit) {
1045
1172
  this.controlSends.delete(helloKey);
1173
+ this.refreshAdmissionPending(nowMs);
1046
1174
  if (result === 'notRequired') {
1047
1175
  this.retireNotRequiredExpectedPeer(received.sourceRid, descriptor.advertisedEndpoint);
1048
1176
  } else if (
@@ -1126,12 +1254,7 @@ export class RawServiceMeshRuntime {
1126
1254
  if (
1127
1255
  header.flags !== 0 ||
1128
1256
  received.parts.length !== 2 ||
1129
- ![
1130
- M6aServiceWireCommand.nodeSend,
1131
- M6aServiceWireCommand.nodeRequest,
1132
- M6aServiceWireCommand.channelSend,
1133
- M6aServiceWireCommand.channelRequest
1134
- ].includes(header.command as never)
1257
+ !isApplicationEnvelopeCommand(header.command)
1135
1258
  ) {
1136
1259
  return 'protocolError';
1137
1260
  }
@@ -1170,9 +1293,9 @@ export class RawServiceMeshRuntime {
1170
1293
  parts: received.parts,
1171
1294
  sourceRoutingId: received.sourceRid,
1172
1295
  sourceRoute: received.sourceRoute,
1173
- ...(received.reply === undefined ? {} : { reply: received.reply }),
1296
+ reply: received.reply,
1174
1297
  requestSequence: received.requestSeq,
1175
- ...(correlation === undefined ? {} : { correlation }),
1298
+ correlation,
1176
1299
  applicationJob
1177
1300
  });
1178
1301
  if (accepted) return 'application';
@@ -1200,10 +1323,42 @@ export class RawServiceMeshRuntime {
1200
1323
  return this.operations.size;
1201
1324
  }
1202
1325
 
1326
+ cancelPendingOperations(reason: unknown): void {
1327
+ this.operations.failAll(reason);
1328
+ }
1329
+
1330
+ /**
1331
+ * The next management deadline of this node (spec 08 §4.2): request expiry,
1332
+ * liveness probe or timeout, or an owned HELLO exchange still awaiting
1333
+ * ADMIT, which keeps the existing announce cadence.
1334
+ */
1335
+ nextMaintenanceDeadlineMs(nowMs: number): number {
1336
+ this.refreshAdmissionPending(nowMs);
1337
+ return Math.min(this.operations.nextDeadlineMs(), this.liveness.nextDeadlineMs());
1338
+ }
1339
+
1340
+ private refreshAdmissionPending(nowMs: number): void {
1341
+ let pending = false;
1342
+ if (!this.closed && this.controlSends.size !== 0) {
1343
+ for (const nodeRoutingId of this.selectedRoutes.keys()) {
1344
+ const exchange = this.controlSends.get(
1345
+ controlSendKey(nodeRoutingId, M6aServiceWireCommand.hello)
1346
+ );
1347
+ if (exchange?.current?.() === true) {
1348
+ pending = true;
1349
+ break;
1350
+ }
1351
+ }
1352
+ }
1353
+ this.liveness.setAdmissionPending(pending, nowMs);
1354
+ }
1355
+
1203
1356
  tickLiveness(nowMs = performance.now()): ServiceLivenessTick {
1357
+ const admissionDue = this.liveness.tickAdmission(nowMs);
1204
1358
  const result = this.liveness.tick(nowMs);
1205
1359
  this.requireStarted();
1206
- for (const nodeRoutingId of this.selectedRoutes.keys()) void this.announcePeer(nodeRoutingId);
1360
+ if (admissionDue)
1361
+ for (const nodeRoutingId of this.selectedRoutes.keys()) void this.announcePeer(nodeRoutingId);
1207
1362
  for (const probe of result.probes) {
1208
1363
  const parts = [
1209
1364
  livenessCodec.encodeLivenessRecord({
@@ -1257,6 +1412,7 @@ export class RawServiceMeshRuntime {
1257
1412
  for (const nodeRoutingId of selected) this.notifyPeerRouteChanged(nodeRoutingId);
1258
1413
  // A new selected route admits only through a new handshake.
1259
1414
  for (const nodeRoutingId of selected) await this.announcePeer(nodeRoutingId);
1415
+ this.refreshAdmissionPending(performance.now());
1260
1416
  return changes;
1261
1417
  }
1262
1418
 
@@ -1289,15 +1445,16 @@ export class RawServiceMeshRuntime {
1289
1445
  payload: ServiceApplicationPayloadInput,
1290
1446
  timeoutMs: number,
1291
1447
  channelName?: string,
1292
- onAdmitted?: () => void
1293
- ): PendingOperation<RawServiceRequestResult> {
1448
+ onAdmitted?: () => void,
1449
+ observer?: RawServiceRequestObserver,
1450
+ operationKind?: number
1451
+ ): RawServiceObservedRequest {
1294
1452
  const correlation = this.nextCorrelation++;
1295
1453
  const header =
1296
1454
  channelName === undefined
1297
1455
  ? encodeNodeRequestHeader(correlation)
1298
1456
  : encodeChannelRequestHeader(correlation, channelName);
1299
1457
  const encodedPayload = this.applicationFrame(payload);
1300
- const pending = this.operations.register(timeoutMs);
1301
1458
  let selectedTargetNodeRoutingId = targetNodeRoutingId;
1302
1459
  if (
1303
1460
  selectedTargetNodeRoutingId !== this.descriptor.nodeRoutingId &&
@@ -1325,6 +1482,9 @@ export class RawServiceMeshRuntime {
1325
1482
  }
1326
1483
  }
1327
1484
  if (selectedTargetNodeRoutingId === this.descriptor.nodeRoutingId) {
1485
+ // The local admission path aborts its capacity wait on the terminal
1486
+ // Promise, so a local request always keeps the Promise entry.
1487
+ const pending = this.operations.register(timeoutMs);
1328
1488
  const parts = [header, encodedPayload];
1329
1489
  const capacityStop = new AbortController();
1330
1490
  void pending.promise.finally(() => capacityStop.abort()).catch(() => undefined);
@@ -1369,12 +1529,13 @@ export class RawServiceMeshRuntime {
1369
1529
  })().catch((error) => this.operations.fail(pending.id, error));
1370
1530
  return pending;
1371
1531
  }
1532
+ const pending = this.registerRequest(timeoutMs, observer, operationKind);
1372
1533
  const selectedPeer = this.topology.admittedPeer(selectedTargetNodeRoutingId);
1373
1534
  if (selectedPeer === undefined) {
1374
1535
  // Logical target selection is the requester's decision: an RID that is
1375
1536
  // not an admitted peer is not a target. Whether an admitted target's
1376
1537
  // route can carry the request is Core's REQUEST result.
1377
- this.operations.complete(pending.id, {
1538
+ this.completeRequest(pending, {
1378
1539
  terminalResult: RequestResult.NotFound,
1379
1540
  failureCode: REQUEST_TARGET_NOT_FOUND_FAILURE_CODE
1380
1541
  });
@@ -1391,7 +1552,7 @@ export class RawServiceMeshRuntime {
1391
1552
  onAdmitted
1392
1553
  );
1393
1554
  } catch (error) {
1394
- this.operations.fail(pending.id, error);
1555
+ this.failRequest(pending, error);
1395
1556
  return pending;
1396
1557
  }
1397
1558
  void request.then(
@@ -1568,6 +1729,8 @@ export class RawServiceMeshRuntime {
1568
1729
  hello?: Uint8Array
1569
1730
  ): boolean {
1570
1731
  const key = controlSendKey(target, command);
1732
+ if (command === M6aServiceWireCommand.hello)
1733
+ this.liveness.setAdmissionPending(true, performance.now());
1571
1734
  const existing = this.controlSends.get(key);
1572
1735
  if (
1573
1736
  existing !== undefined &&
@@ -1607,16 +1770,19 @@ export class RawServiceMeshRuntime {
1607
1770
  () => {},
1608
1771
  (error) => {
1609
1772
  completeSend();
1610
- if (this.infrastructureTaskRunner === undefined) this.reportInfrastructureFailure(error);
1773
+ this.reportInfrastructureFailure(error);
1611
1774
  }
1612
1775
  );
1613
- this.infrastructureTaskRunner?.runDetached('RouteMesh control SEND', async () => {
1614
- await task;
1615
- });
1616
1776
  return true;
1617
1777
  }
1618
1778
 
1619
- private reportInfrastructureFailure(error: unknown): void {
1779
+ reportInfrastructureFailure(error: unknown): void {
1780
+ if (this.infrastructureTaskRunner !== undefined) {
1781
+ this.infrastructureTaskRunner.runDetached('RouteMesh infrastructure', async () => {
1782
+ throw error;
1783
+ });
1784
+ return;
1785
+ }
1620
1786
  this.infrastructureFailure = {
1621
1787
  error:
1622
1788
  this.infrastructureFailure === undefined
@@ -1662,7 +1828,7 @@ export class RawServiceMeshRuntime {
1662
1828
  }
1663
1829
 
1664
1830
  function controlSendKey(target: string, command: number): string {
1665
- return JSON.stringify([target, command]);
1831
+ return `${command}:${target}`;
1666
1832
  }
1667
1833
 
1668
1834
  function routeConnectionId(generation: bigint): string {
@@ -1674,20 +1840,31 @@ function routeConnectionId(generation: bigint): string {
1674
1840
  * not application NodeSend(16) envelopes. Keep this list closed: a bare
1675
1841
  * record outside the frozen control vocabulary remains a protocol error.
1676
1842
  */
1843
+ const BARE_INFRASTRUCTURE_CONTROLS: ReadonlySet<number> = new Set<number>([
1844
+ ServiceWireCommand.relocationReady,
1845
+ ServiceWireCommand.relocationData,
1846
+ ServiceWireCommand.replyRelay,
1847
+ ServiceWireCommand.relocationCutover,
1848
+ ServiceWireCommand.relocationPrepare,
1849
+ ServiceWireCommand.sessionRelocationSeal,
1850
+ ServiceWireCommand.sessionRelocationSealed,
1851
+ ServiceWireCommand.sessionRelocationRoute,
1852
+ ServiceWireCommand.replyRelayAck,
1853
+ ServiceWireCommand.relocationState,
1854
+ ServiceWireCommand.relocationFailed
1855
+ ]);
1856
+
1677
1857
  function isBareInfrastructureControl(command: number): boolean {
1678
- return [
1679
- ServiceWireCommand.relocationReady,
1680
- ServiceWireCommand.relocationData,
1681
- ServiceWireCommand.replyRelay,
1682
- ServiceWireCommand.relocationCutover,
1683
- ServiceWireCommand.relocationPrepare,
1684
- ServiceWireCommand.sessionRelocationSeal,
1685
- ServiceWireCommand.sessionRelocationSealed,
1686
- ServiceWireCommand.sessionRelocationRoute,
1687
- ServiceWireCommand.replyRelayAck,
1688
- ServiceWireCommand.relocationState,
1689
- ServiceWireCommand.relocationFailed
1690
- ].includes(command as never);
1858
+ return BARE_INFRASTRUCTURE_CONTROLS.has(command);
1859
+ }
1860
+
1861
+ function isApplicationEnvelopeCommand(command: number): boolean {
1862
+ return (
1863
+ command === M6aServiceWireCommand.nodeSend ||
1864
+ command === M6aServiceWireCommand.nodeRequest ||
1865
+ command === M6aServiceWireCommand.channelSend ||
1866
+ command === M6aServiceWireCommand.channelRequest
1867
+ );
1691
1868
  }
1692
1869
 
1693
1870
  function protocolCommand(parts: readonly Uint8Array[]): { readonly command?: number } {
@@ -54,9 +54,20 @@ export class ServiceLivenessConnection {
54
54
  }
55
55
 
56
56
  /** Uses monotonic milliseconds and never treats application traffic as a probe ACK. */
57
+ const NO_LIVENESS_WORK: ServiceLivenessTick = Object.freeze({
58
+ probes: Object.freeze([]) as readonly ServiceProbe[],
59
+ timedOutNodes: Object.freeze([]) as readonly string[]
60
+ });
61
+
57
62
  export class ServiceLivenessRegistry {
58
63
  private readonly peers = new Map<string, ServiceLivenessConnection>();
59
64
  private nextProbeId = 1n;
65
+ /**
66
+ * The earliest probe or timeout among admitted peers. Received traffic only
67
+ * extends a peer's deadline, so this stays a lower bound between ticks.
68
+ */
69
+ private nextDueMs = Number.POSITIVE_INFINITY;
70
+ private admissionActivityMs?: number;
60
71
 
61
72
  constructor(
62
73
  private readonly probeIntervalMs = DEFAULT_SERVICE_PROBE_INTERVAL_MS,
@@ -89,9 +100,33 @@ export class ServiceLivenessRegistry {
89
100
  this.peerTimeoutMs
90
101
  );
91
102
  this.peers.set(nodeRoutingId, admitted);
103
+ this.nextDueMs = Math.min(this.nextDueMs, admitted.nextProbeMs, admitted.deadlineMs);
92
104
  return admitted;
93
105
  }
94
106
 
107
+ /** When the next tick has probe or timeout work (spec 08 §4.2 management deadline). */
108
+ nextDeadlineMs(): number {
109
+ return Math.min(this.nextDueMs, this.nextAdmissionDeadlineMs());
110
+ }
111
+
112
+ /** Pending admission shares the existing liveness management cadence (MeshNode §7.1). */
113
+ setAdmissionPending(pending: boolean, nowMs: number): void {
114
+ if (pending) this.admissionActivityMs ??= nowMs;
115
+ else this.admissionActivityMs = undefined;
116
+ }
117
+
118
+ private nextAdmissionDeadlineMs(): number {
119
+ return this.admissionActivityMs === undefined
120
+ ? Number.POSITIVE_INFINITY
121
+ : this.admissionActivityMs + this.probeIntervalMs;
122
+ }
123
+
124
+ tickAdmission(nowMs: number): boolean {
125
+ if (nowMs < this.nextAdmissionDeadlineMs()) return false;
126
+ this.admissionActivityMs = nowMs;
127
+ return true;
128
+ }
129
+
95
130
  recordReceived(connection: ServiceLivenessConnection, nowMs: number): void {
96
131
  connection.recordReceived(nowMs);
97
132
  }
@@ -127,8 +162,10 @@ export class ServiceLivenessRegistry {
127
162
  }
128
163
 
129
164
  tick(nowMs: number): ServiceLivenessTick {
165
+ if (nowMs < this.nextDeadlineMs()) return NO_LIVENESS_WORK;
130
166
  const probes: ServiceProbe[] = [];
131
167
  const timedOutNodes: string[] = [];
168
+ let nextDueMs = Number.POSITIVE_INFINITY;
132
169
  for (const [nodeRoutingId, peer] of this.peers) {
133
170
  if (peer.isExpired(nowMs)) {
134
171
  timedOutNodes.push(nodeRoutingId);
@@ -138,7 +175,9 @@ export class ServiceLivenessRegistry {
138
175
  const probeId = peer.tryGetProbe(nowMs, this.allocateProbeId);
139
176
  if (probeId !== undefined)
140
177
  probes.push({ nodeRoutingId, connectionId: peer.connectionId, probeId });
178
+ nextDueMs = Math.min(nextDueMs, peer.nextProbeMs, peer.deadlineMs);
141
179
  }
180
+ this.nextDueMs = nextDueMs;
142
181
  timedOutNodes.sort();
143
182
  return { probes, timedOutNodes };
144
183
  }
@@ -1,13 +1,21 @@
1
1
  import type { ApplicationJobRecordLease } from '../application-jobs/application-ingress-record-owner';
2
2
  import type { ReceiveRecord } from './service-runtime-contracts';
3
+ import type { RawServiceIngressRecord } from './raw-service-mesh-runtime';
3
4
 
4
5
  export type ServiceMailboxDomain = 'application' | 'infrastructure';
5
6
 
7
+ export interface ServiceMailboxDispatchOwner {
8
+ prepareDispatch(record: ServiceMailboxRecord, signal: AbortSignal): boolean | Promise<boolean>;
9
+ }
10
+
6
11
  export interface ServiceMailboxRecord {
12
+ readonly sourcePreparationOwner?: ServiceMailboxDispatchOwner;
13
+ readonly ingress?: RawServiceIngressRecord;
7
14
  readonly owner: string;
8
15
  readonly domain: ServiceMailboxDomain;
9
16
  parts: readonly Uint8Array[];
10
17
  readonly sourceRoutingId?: string;
18
+ readonly requestSource?: import('../locations/request-source-resolver').ZLinkRequestSourceFence;
11
19
  readonly sourceRoute?: Uint8Array;
12
20
  readonly requestSequence?: bigint;
13
21
  readonly reply?: (parts: readonly Uint8Array[]) => void;
@@ -1,7 +1,4 @@
1
- import { AsyncResource } from 'node:async_hooks';
2
- import { ZLinkStateLane } from '../execution/state-lane';
3
-
4
- const detachedStateLaneResource = new AsyncResource('zlink:service-maintenance-runtime');
1
+ import { startOutsideStateLane, ZLinkStateLane } from '../execution/state-lane';
5
2
 
6
3
  export type ServiceMaintenanceKind = 'retire' | 'shutdown';
7
4
  export type ServiceMaintenanceState =
@@ -248,7 +245,3 @@ export class ServiceMaintenanceRuntime {
248
245
  for (const observer of publication.observers) observer(publication.snapshot);
249
246
  }
250
247
  }
251
-
252
- function startOutsideStateLane<T>(work: () => T): T {
253
- return detachedStateLaneResource.runInAsyncScope(work);
254
- }