@@ -5,6 +5,7 @@ import type { TrackReader } from "./objects"
55import { debug } from "./utils"
66import { ControlStream } from "./stream"
77import { SubgroupReader } from "./subgroup"
8+ import { MigrationState } from "./connection"
89
910export interface TrackInfo {
1011 track_alias : bigint
@@ -15,6 +16,9 @@ export class Subscriber {
1516 // Use to send control messages.
1617 #control: ControlStream
1718
19+ #migrationState: MigrationState = "none"
20+ #tracksToMigrate = new Set < [ string [ ] , string ] > ( )
21+
1822 // Use to send objects.
1923 #objects: Objects
2024
@@ -38,6 +42,24 @@ export class Subscriber {
3842 return this . #publishedNamespacesQueue
3943 }
4044
45+ async startMigration ( ) {
46+ this . #migrationState = "in_progress"
47+ // close all the subscription
48+ this . #trackToIDMap. forEach ( async ( id , track ) => {
49+ await this . unsubscribe ( track , true ) ;
50+ } )
51+ }
52+
53+ async migrationDone ( control : ControlStream , objects : Objects ) {
54+ this . #migrationState = "done"
55+ this . #control = control
56+ this . #objects = objects
57+ this . #tracksToMigrate. forEach ( async ( track ) => {
58+ await this . subscribe ( track [ 0 ] , track [ 1 ] ) ;
59+ } )
60+ this . #tracksToMigrate. clear ( )
61+ }
62+
4163 async recv ( msg : Control . MessageWithType ) {
4264 const { type, message } = msg ;
4365 switch ( type ) {
@@ -82,8 +104,10 @@ export class Subscriber {
82104 }
83105
84106 async subscribe_namespace ( namespace : string [ ] ) {
107+ if ( this . #migrationState === "in_progress" ) {
108+ throw new Error ( `migration in progress` )
109+ }
85110 const id = this . #control. nextRequestId ( )
86- // TODO(itzmanish): implement this
87111 const msg : Control . MessageWithType = {
88112 type : Control . ControlMessageType . SubscribeNamespace ,
89113 message : {
@@ -95,6 +119,9 @@ export class Subscriber {
95119 }
96120
97121 async subscribe ( namespace : string [ ] , track : string ) {
122+ if ( this . #migrationState === "in_progress" ) {
123+ throw new Error ( `migration in progress` )
124+ }
98125 const id = this . #control. nextRequestId ( )
99126
100127 const subscribe = new SubscribeSend ( this . #control, id , namespace , track )
@@ -122,22 +149,29 @@ export class Subscriber {
122149 return subscribe
123150 }
124151
125- async unsubscribe ( track : string ) {
126- if ( this . #trackToIDMap. has ( track ) ) {
127- const trackID = this . #trackToIDMap. get ( track )
128- if ( trackID === undefined ) {
129- console . warn ( `Exception track ${ track } not found in trackToIDMap.` )
130- return
131- }
132- try {
133- await this . #control. send ( { type : Control . ControlMessageType . Unsubscribe , message : { id : trackID } } )
134- this . #trackToIDMap. delete ( track )
135- } catch ( error ) {
136- console . error ( `Failed to unsubscribe from track ${ track } :` , error )
152+ async unsubscribe ( track : string , isMigrating = false ) {
153+ const trackID = this . #trackToIDMap. get ( track )
154+
155+ if ( trackID === undefined ) {
156+ console . warn ( `Exception track ${ track } not found in trackToIDMap.` )
157+ return
158+ }
159+
160+ try {
161+ const subscription = this . #subscribe. get ( trackID )
162+ if ( subscription ) {
163+ this . #subscribe. delete ( trackID )
164+ await subscription . close ( )
165+ if ( isMigrating ) {
166+ this . #tracksToMigrate. add ( [ subscription . namespace , track ] )
167+ }
137168 }
138- } else {
139- console . warn ( `During unsubscribe request initiation attempt track ${ track } not found in trackToIDMap.` )
169+ this . #trackToIDMap. delete ( track )
170+
171+ } catch ( error ) {
172+ console . error ( `Failed to unsubscribe from track ${ track } :` , error )
140173 }
174+
141175 }
142176
143177 recvSubscribeOk ( msg : Control . SubscribeOk ) {
@@ -265,8 +299,10 @@ export class SubscribeSend {
265299 }
266300
267301 async close ( _code = 0n , _reason = "" ) {
268- // TODO implement unsubscribe
269- // await this.#inner.sendReset(code, reason)
302+ this . #control. send ( {
303+ type : Control . ControlMessageType . Unsubscribe ,
304+ message : { id : this . #id }
305+ } )
270306 }
271307
272308 onOk ( trackAlias : bigint ) {
0 commit comments