@serve.zone/dcrouter 17.6.1 → 17.7.1
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.
- package/deno.json +1 -1
- package/dist_serve/bundle.js +568 -560
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/db/documents/classes.cached.email.d.ts +9 -1
- package/dist_ts/db/documents/classes.cached.email.js +16 -3
- package/dist_ts/email/classes.accepted-email-spool.js +4 -1
- package/dist_ts/logger.js +6 -1
- package/dist_ts/opsserver/handlers/email-ops.handler.js +10 -1
- package/dist_ts_interfaces/requests/email-ops.d.ts +4 -0
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/package.json +3 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/db/documents/classes.cached.email.ts +11 -1
- package/ts/email/classes.accepted-email-spool.ts +3 -0
- package/ts/logger.ts +6 -0
- package/ts/opsserver/handlers/email-ops.handler.ts +9 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
|
@@ -875,9 +875,11 @@ export class AcceptedEmailSpool {
|
|
|
875
875
|
cachedEmail.status = 'deferred';
|
|
876
876
|
cachedEmail.lastError = item.lastError || 'SmartMTA delivery deferred';
|
|
877
877
|
const smartMtaNextAttempt = item.nextAttempt || new Date(Date.now() + ACCEPTED_EMAIL_RETRY_DELAY_MS);
|
|
878
|
+
cachedEmail.smartMtaNextAttempt = smartMtaNextAttempt;
|
|
878
879
|
cachedEmail.nextAttempt = new Date(smartMtaNextAttempt.getTime() + ACCEPTED_EMAIL_QUEUE_LEASE_MS);
|
|
879
880
|
} else {
|
|
880
881
|
cachedEmail.status = 'queued';
|
|
882
|
+
cachedEmail.smartMtaNextAttempt = undefined;
|
|
881
883
|
cachedEmail.nextAttempt = new Date(Date.now() + ACCEPTED_EMAIL_QUEUE_LEASE_MS);
|
|
882
884
|
}
|
|
883
885
|
await cachedEmail.save();
|
|
@@ -954,6 +956,7 @@ export class AcceptedEmailSpool {
|
|
|
954
956
|
}
|
|
955
957
|
this.updateSmartMtaRouteData(cachedEmail, queueItem, status);
|
|
956
958
|
const smartMtaNextAttempt = queueItem.nextAttempt || new Date(Date.now() + ACCEPTED_EMAIL_RETRY_DELAY_MS);
|
|
959
|
+
cachedEmail.smartMtaNextAttempt = status === 'deferred' ? smartMtaNextAttempt : undefined;
|
|
957
960
|
cachedEmail.nextAttempt = new Date(smartMtaNextAttempt.getTime() + ACCEPTED_EMAIL_QUEUE_LEASE_MS);
|
|
958
961
|
await cachedEmail.save();
|
|
959
962
|
await this.notifyEmailQueuePersisted(cachedEmail, 'email-live-queue-postponed');
|
package/ts/logger.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { SmartlogDestinationBuffer } from '@push.rocks/smartlog/destination-buffer';
|
|
4
|
+
import { DestinationLocal } from '@push.rocks/smartlog/destination-local';
|
|
4
5
|
|
|
5
6
|
// Map NODE_ENV to valid TEnvironment
|
|
6
7
|
const nodeEnv = process.env.NODE_ENV || 'production';
|
|
@@ -26,6 +27,11 @@ export const baseLogger = new plugins.smartlog.Smartlog({
|
|
|
26
27
|
// Wire the buffer destination so all logs are captured
|
|
27
28
|
baseLogger.addLogDestination(logBuffer);
|
|
28
29
|
|
|
30
|
+
// Also write to the process console: without this, dcrouter-level logs (e.g.
|
|
31
|
+
// RemoteIngress egress failures) exist only in the in-memory ops buffer and are
|
|
32
|
+
// invisible to process-manager log capture.
|
|
33
|
+
baseLogger.addLogDestination(new DestinationLocal());
|
|
34
|
+
|
|
29
35
|
// Extended logger compatible with the original enhanced logger API
|
|
30
36
|
class StandardLogger {
|
|
31
37
|
private defaultContext: Record<string, any> = {};
|
|
@@ -180,9 +180,18 @@ export class EmailOpsHandler {
|
|
|
180
180
|
const { headers, body } = this.parseRawEmail(rawContent);
|
|
181
181
|
const session = this.parseCachedEmailSession(doc);
|
|
182
182
|
|
|
183
|
+
// Display SmartMTA's true retry schedule — doc.nextAttempt is the spool's
|
|
184
|
+
// recovery lease (retry time + 30min grace), not the user-facing countdown.
|
|
185
|
+
const nextAttemptMs = doc.smartMtaNextAttempt ? new Date(doc.smartMtaNextAttempt).getTime() : NaN;
|
|
183
186
|
return {
|
|
184
187
|
...base,
|
|
185
188
|
smtpTransactions: structuredClone(doc.smtpTransactions || []),
|
|
189
|
+
...(base.status === 'deferred' && Number.isFinite(nextAttemptMs) && nextAttemptMs > 0
|
|
190
|
+
? {
|
|
191
|
+
nextAttemptAt: nextAttemptMs,
|
|
192
|
+
nextAttemptNumber: (doc.attempts || 0) + 1,
|
|
193
|
+
}
|
|
194
|
+
: {}),
|
|
186
195
|
toList: doc.to || [],
|
|
187
196
|
cc: doc.cc || [],
|
|
188
197
|
smtpLog: this.flattenSmtpTransactions(doc.smtpTransactions || []),
|