@@ -38,8 +38,8 @@ export class PaymentListenerDurable extends DurableObject<Env> {
38
38
throw new Error ( e . message ) ;
39
39
} ) ;
40
40
41
- this . nanoWebsocket . onClose ( ( e ) => {
42
- if ( e . code !== 1000 || ! this . nanoWebsocket . closedByClient ) {
41
+ this . nanoWebsocket . onClose ( ( e , closedByClient ) => {
42
+ if ( e . code !== 1000 || ! closedByClient ) {
43
43
throw new Error ( `Websocket connection closed: ${ this . env . NANO_WEBSOCKET_URL } ${ e . reason ? ', ' + e . reason : '' } ` ) ;
44
44
}
45
45
} ) ;
@@ -51,14 +51,14 @@ export class PaymentListenerDurable extends DurableObject<Env> {
51
51
this . onPayment ( payment , invoice , service , webhooks ) ;
52
52
} ) ;
53
53
54
- await this . alarm ( ) ;
55
-
56
54
this . pendingInvoices . push ( {
57
55
id : invoice . id ,
58
56
expiresAt : invoice . expires_at ,
59
57
payAddress : invoice . pay_address ,
60
58
payments : [ ] ,
61
59
} ) ;
60
+
61
+ await this . alarm ( ) ;
62
62
}
63
63
64
64
private async onPayment ( payment : SendEvent , invoice : Invoice , service : Service , webhooks : Webhook [ ] ) {
@@ -147,7 +147,10 @@ export class PaymentListenerDurable extends DurableObject<Env> {
147
147
}
148
148
149
149
async alarm ( ) {
150
- this . pendingInvoices . forEach ( async ( activeInvoice ) => {
150
+ /*
151
+ Alarm: Expire invoices, keep websocket connection alive or close it
152
+ */
153
+ for ( const activeInvoice of this . pendingInvoices ) {
151
154
const expired = new Date ( activeInvoice . expiresAt ) . getTime ( ) < Date . now ( ) ;
152
155
if ( expired ) {
153
156
logger . info ( `Invoice expired: ${ activeInvoice . id } ` , {
@@ -156,15 +159,20 @@ export class PaymentListenerDurable extends DurableObject<Env> {
156
159
this . nanoWebsocket . unsubscribe ( activeInvoice . payAddress ) ;
157
160
this . removePendingInvoice ( activeInvoice . id ) ;
158
161
}
159
- } ) ;
160
- if ( this . nanoWebsocket . listeningAccounts . length > 0 ) {
162
+ }
163
+ if ( this . pendingInvoices . length > 0 ) {
161
164
const currentAlarm = await this . ctx . storage . getAlarm ( ) ;
162
165
if ( ! currentAlarm ) {
163
- // Call alarm to keep websocket connection alive
164
- this . ctx . storage . setAlarm ( Date . now ( ) + 1000 * 15 ) ;
166
+ const nearestExpiresAt = this . pendingInvoices . reduce ( ( acc , activeInvoice ) => {
167
+ return acc < new Date ( activeInvoice . expiresAt ) . getTime ( ) ? acc : new Date ( activeInvoice . expiresAt ) . getTime ( ) ;
168
+ } , Infinity ) ;
169
+
170
+ const defaultScheduledTime = Date . now ( ) + 1000 * 30 ; // 30 seconds
171
+ const scheduledTime = nearestExpiresAt < defaultScheduledTime ? nearestExpiresAt : defaultScheduledTime ;
172
+
173
+ this . ctx . storage . setAlarm ( scheduledTime ) ;
165
174
}
166
175
} else {
167
- // No more listening accounts, close the websocket connection
168
176
this . nanoWebsocket . close ( ) ;
169
177
}
170
178
}
0 commit comments