Put a receipt's segments on the wire together, like a message's
This commit is contained in:
@@ -84,8 +84,12 @@ export class OutgoingRequests {
|
||||
|
||||
if (refused) return { err: refused };
|
||||
|
||||
// A bind is what makes a link usable, so it cannot wait for one.
|
||||
if (bindCommands.includes(input.cmdName)) return this.now(input, options);
|
||||
// A bind is what makes a link usable, so it cannot wait for one: it takes the gate's answer now.
|
||||
if (bindCommands.includes(input.cmdName)) {
|
||||
const shut = this.gate.refusal();
|
||||
|
||||
return shut ? { err: shut } : this.now(input, options);
|
||||
}
|
||||
|
||||
const waitForLink = this.gate.hold(options.signal);
|
||||
|
||||
@@ -131,10 +135,7 @@ export class OutgoingRequests {
|
||||
}
|
||||
|
||||
// Before the gate and the window, or an aborted call waits for what it will never use.
|
||||
if (options.signal?.aborted === true) return abortedBeforeSend();
|
||||
|
||||
// A bind skips the gate below, so the answer it would have given is given here instead.
|
||||
return bindCommands.includes(input.cmdName) ? this.gate.refusal() : undefined;
|
||||
return options.signal?.aborted === true ? abortedBeforeSend() : undefined;
|
||||
}
|
||||
|
||||
private async attempt(input: PduObjectInput, options: SendOptions): Promise<Attempt> {
|
||||
|
||||
+14
-3
@@ -304,10 +304,8 @@ export class Session extends EventEmitter<SessionEvents> {
|
||||
|
||||
const timeout = this.options.shutdownTimeout ?? defaults.shutdownTimeout;
|
||||
const deadline = timeout > 0 ? Date.now() + timeout : 0;
|
||||
// Only the application answers a held message, so that half falls back rather than wait forever.
|
||||
const answering = timeout > 0 ? timeout : (this.options.responseTimeout ?? defaults.responseTimeout);
|
||||
// Answering a message can put a receipt on the wire; nothing on the wire produces a message.
|
||||
const messages = await this.incoming.drain(answering, signal);
|
||||
const messages = await this.incoming.drain(this.answering(timeout), signal);
|
||||
const requests = await this.outgoing.drain(leftOf(deadline), signal);
|
||||
|
||||
// The window empties on a teardown too, which settles everything the link was carrying.
|
||||
@@ -318,6 +316,19 @@ export class Session extends EventEmitter<SessionEvents> {
|
||||
return messages.err ? messages : requests;
|
||||
}
|
||||
|
||||
/**
|
||||
* How long the drain waits for the application, which is the only thing that can end that wait.
|
||||
* Neither timeout may hand it "forever": both are answers about a peer, and a peer is not what
|
||||
* this half is waiting for.
|
||||
*/
|
||||
private answering(timeout: number): number {
|
||||
if (timeout > 0) return timeout;
|
||||
|
||||
const responseTimeout = this.options.responseTimeout ?? defaults.responseTimeout;
|
||||
|
||||
return responseTimeout > 0 ? responseTimeout : defaults.responseTimeout;
|
||||
}
|
||||
|
||||
/** The session is over now, drained or not. Nothing brings it back. */
|
||||
private end(): void {
|
||||
this.reconnectLoop?.stop();
|
||||
|
||||
+9
-6
@@ -138,11 +138,11 @@ async function sendDlr(
|
||||
}
|
||||
|
||||
const total = sms.pduObjs.length;
|
||||
const pduObjs: PduObject[] = [];
|
||||
|
||||
for (let index = 0; index < total; index++) {
|
||||
// Together, not one after a response: a drain waiting for this message must see the whole receipt.
|
||||
const sent = await Promise.all(sms.pduObjs.map((_segment, index) => {
|
||||
const smsId = segmentId(sms.smsId, index, total);
|
||||
const sent = await send({
|
||||
|
||||
return send({
|
||||
cmdName: 'deliver_sm',
|
||||
params: {
|
||||
destination_addr: sms.from,
|
||||
@@ -152,10 +152,13 @@ async function sendDlr(
|
||||
},
|
||||
...(sms.session.acceptsOptionalParams() ? { tlvs: receiptTlvs(smsId, status) } : {}),
|
||||
});
|
||||
}));
|
||||
const pduObjs: PduObject[] = [];
|
||||
|
||||
if (sent.err) return { err: sent.err };
|
||||
for (const one of sent) {
|
||||
if (one.err) return { err: one.err };
|
||||
|
||||
pduObjs.push(sent.pduObj);
|
||||
pduObjs.push(one.pduObj);
|
||||
}
|
||||
|
||||
return { pduObjs };
|
||||
|
||||
Reference in New Issue
Block a user