backend-manager 5.9.20 → 5.9.21
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/package.json +1 -1
- package/src/manager/events/cron/daily/marketing-prune.js +121 -29
- package/src/test/fixtures/firebase-project/.temp/test-mode.json +1 -1
- package/src/test/fixtures/firebase-project/database-debug.log +8 -8
- package/src/test/fixtures/firebase-project/firestore-debug.log +51 -63
- package/src/test/fixtures/firebase-project/pubsub-debug.log +3 -3
package/package.json
CHANGED
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
* Two-stage process using SSOT segment keys from constants.js:
|
|
6
6
|
*
|
|
7
7
|
* Stage 1 (engagement_inactive_5m):
|
|
8
|
-
* → Send re-engagement email via sendCampaign
|
|
8
|
+
* → Send re-engagement email via sendCampaign (brand-scoped internally)
|
|
9
9
|
* → Excludes engagement_inactive_6m (those get pruned instead)
|
|
10
10
|
*
|
|
11
11
|
* Stage 2 (engagement_inactive_6m):
|
|
12
|
-
* →
|
|
13
|
-
* →
|
|
12
|
+
* → Create brand-scoped temp segment via createBrandScopedSegment
|
|
13
|
+
* → Export contacts, exclude paying customers, bulk delete
|
|
14
|
+
* → Log deleted emails to Firestore for recoverability
|
|
15
|
+
* → Remove from Beehiiv (same emails)
|
|
14
16
|
*
|
|
15
17
|
* Segment keys are resolved to provider-specific IDs at runtime.
|
|
16
18
|
* Requires marketing.prune.enabled = true in backend-manager-config.json.
|
|
@@ -19,8 +21,7 @@
|
|
|
19
21
|
*/
|
|
20
22
|
const sendgridProvider = require('../../../libraries/email/providers/sendgrid.js');
|
|
21
23
|
|
|
22
|
-
module.exports = async ({ Manager, assistant }) => {
|
|
23
|
-
// Only run on the 1st of the month
|
|
24
|
+
module.exports = async ({ Manager, assistant, libraries }) => {
|
|
24
25
|
if (new Date().getDate() !== 1) {
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
@@ -30,20 +31,29 @@ module.exports = async ({ Manager, assistant }) => {
|
|
|
30
31
|
return;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
const brand = Manager.config?.brand;
|
|
35
|
+
|
|
36
|
+
assistant.log(`Marketing prune: Starting monthly prune cycle for ${brand?.id || 'unknown'}`);
|
|
34
37
|
|
|
35
38
|
// --- Stage 1: Re-engagement email ---
|
|
36
|
-
|
|
39
|
+
try {
|
|
40
|
+
await stageReengage(Manager, assistant);
|
|
41
|
+
} catch (e) {
|
|
42
|
+
assistant.error('Marketing prune: Stage 1 (re-engagement) failed:', e.message);
|
|
43
|
+
}
|
|
37
44
|
|
|
38
45
|
// --- Stage 2: Delete inactive contacts ---
|
|
39
|
-
await stagePrune(Manager, assistant);
|
|
46
|
+
await stagePrune(Manager, assistant, libraries);
|
|
40
47
|
|
|
41
|
-
assistant.log(
|
|
48
|
+
assistant.log(`Marketing prune: Completed for ${brand?.id || 'unknown'}`);
|
|
42
49
|
};
|
|
43
50
|
|
|
44
51
|
/**
|
|
45
52
|
* Stage 1: Send re-engagement email to contacts inactive 5+ months
|
|
46
|
-
* (excluding 6+ months — those get pruned in stage 2)
|
|
53
|
+
* (excluding 6+ months — those get pruned in stage 2).
|
|
54
|
+
*
|
|
55
|
+
* sendCampaign handles brand-scoping internally via _resolveAudience →
|
|
56
|
+
* createBrandScopedSegment, so this stage is already brand-safe.
|
|
47
57
|
*/
|
|
48
58
|
async function stageReengage(Manager, assistant) {
|
|
49
59
|
assistant.log('Marketing prune: Stage 1 — Re-engagement');
|
|
@@ -76,26 +86,51 @@ async function stageReengage(Manager, assistant) {
|
|
|
76
86
|
}
|
|
77
87
|
|
|
78
88
|
/**
|
|
79
|
-
* Stage 2: Delete contacts inactive 6+ months.
|
|
80
|
-
*
|
|
81
|
-
*
|
|
89
|
+
* Stage 2: Delete contacts inactive 6+ months (brand-scoped).
|
|
90
|
+
*
|
|
91
|
+
* Uses createBrandScopedSegment to AND the engagement_inactive_6m query
|
|
92
|
+
* with brand_id = '<brandId>' — each brand only prunes its own contacts.
|
|
93
|
+
* Excludes paying customers (subscription_paid segment).
|
|
94
|
+
* Logs deleted emails to Firestore for recoverability.
|
|
82
95
|
*/
|
|
83
|
-
async function stagePrune(Manager, assistant) {
|
|
96
|
+
async function stagePrune(Manager, assistant, libraries) {
|
|
84
97
|
assistant.log('Marketing prune: Stage 2 — Prune');
|
|
85
98
|
|
|
86
99
|
const marketing = Manager.config?.marketing || {};
|
|
100
|
+
const brand = Manager.config?.brand;
|
|
101
|
+
const { admin } = libraries;
|
|
87
102
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
103
|
+
if (!brand?.id) {
|
|
104
|
+
assistant.error('Marketing prune: brand.id is missing — aborting to prevent account-global deletion');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
92
107
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
if (marketing.campaigns?.enabled === false || !process.env.SENDGRID_API_KEY) {
|
|
109
|
+
assistant.log('Marketing prune: SendGrid not configured, skipping');
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const segmentIdMap = await sendgridProvider.resolveSegmentIds();
|
|
114
|
+
const pruneSegmentId = segmentIdMap['engagement_inactive_6m'];
|
|
97
115
|
|
|
98
|
-
|
|
116
|
+
if (!pruneSegmentId) {
|
|
117
|
+
assistant.error('Marketing prune: engagement_inactive_6m segment not found in SendGrid');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Brand-scope the prune segment
|
|
122
|
+
const tempPrune = await sendgridProvider.createBrandScopedSegment(
|
|
123
|
+
[pruneSegmentId],
|
|
124
|
+
brand.id,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
if (!tempPrune) {
|
|
128
|
+
assistant.error('Marketing prune: Failed to create brand-scoped prune segment');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const exportResult = await sendgridProvider.getSegmentContacts(tempPrune.segmentId, 180000);
|
|
99
134
|
|
|
100
135
|
if (!exportResult.success) {
|
|
101
136
|
assistant.error('Marketing prune: Failed to export segment:', exportResult.error);
|
|
@@ -107,9 +142,45 @@ async function stagePrune(Manager, assistant) {
|
|
|
107
142
|
return;
|
|
108
143
|
}
|
|
109
144
|
|
|
110
|
-
|
|
145
|
+
// Exclude paying customers
|
|
146
|
+
let contactsToPrune = exportResult.contacts;
|
|
147
|
+
let skippedPaid = 0;
|
|
148
|
+
|
|
149
|
+
const paidSegmentId = segmentIdMap['subscription_paid'];
|
|
150
|
+
|
|
151
|
+
if (paidSegmentId) {
|
|
152
|
+
const tempPaid = await sendgridProvider.createBrandScopedSegment(
|
|
153
|
+
[paidSegmentId],
|
|
154
|
+
brand.id,
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
if (tempPaid) {
|
|
158
|
+
try {
|
|
159
|
+
const paidExport = await sendgridProvider.getSegmentContacts(tempPaid.segmentId, 180000);
|
|
160
|
+
|
|
161
|
+
if (paidExport.success && paidExport.contacts.length > 0) {
|
|
162
|
+
const paidEmails = new Set(paidExport.contacts.map(c => c.email));
|
|
163
|
+
contactsToPrune = contactsToPrune.filter(c => !paidEmails.has(c.email));
|
|
164
|
+
skippedPaid = exportResult.contacts.length - contactsToPrune.length;
|
|
165
|
+
assistant.log(`Marketing prune: Excluded ${skippedPaid} paying customers`);
|
|
166
|
+
}
|
|
167
|
+
} finally {
|
|
168
|
+
await tempPaid.cleanup();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (contactsToPrune.length === 0) {
|
|
174
|
+
assistant.log('Marketing prune: No contacts to prune after paid exclusion');
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const emails = contactsToPrune.map(c => c.email).filter(Boolean);
|
|
179
|
+
|
|
180
|
+
assistant.log(`Marketing prune: Deleting ${contactsToPrune.length} contacts for ${brand.id}`);
|
|
111
181
|
|
|
112
|
-
|
|
182
|
+
// Delete from SendGrid
|
|
183
|
+
const ids = contactsToPrune.map(c => c.id).filter(Boolean);
|
|
113
184
|
let totalDeleted = 0;
|
|
114
185
|
|
|
115
186
|
for (let i = 0; i < ids.length; i += 100) {
|
|
@@ -123,18 +194,39 @@ async function stagePrune(Manager, assistant) {
|
|
|
123
194
|
}
|
|
124
195
|
}
|
|
125
196
|
|
|
126
|
-
assistant.log(`Marketing prune: Deleted ${totalDeleted} SendGrid contacts`);
|
|
197
|
+
assistant.log(`Marketing prune: Deleted ${totalDeleted} SendGrid contacts for ${brand.id}`);
|
|
127
198
|
|
|
128
|
-
//
|
|
199
|
+
// Remove from Beehiiv (before Firestore log — a failed log shouldn't skip BH cleanup)
|
|
129
200
|
if (marketing.newsletter?.enabled !== false && process.env.BEEHIIV_API_KEY) {
|
|
130
201
|
const beehiivProvider = require('../../../libraries/email/providers/beehiiv.js');
|
|
131
|
-
const emails = exportResult.contacts.map(c => c.email).filter(Boolean);
|
|
132
202
|
|
|
133
|
-
assistant.log(`Marketing prune: Removing ${emails.length} contacts from Beehiiv`);
|
|
203
|
+
assistant.log(`Marketing prune: Removing ${emails.length} contacts from Beehiiv for ${brand.id}`);
|
|
134
204
|
|
|
135
205
|
await Promise.allSettled(
|
|
136
206
|
emails.map(email => beehiivProvider.removeContact(email))
|
|
137
207
|
);
|
|
138
208
|
}
|
|
209
|
+
|
|
210
|
+
// Log to Firestore for recoverability (non-fatal — don't abort if write fails)
|
|
211
|
+
try {
|
|
212
|
+
const now = new Date();
|
|
213
|
+
const logKey = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
|
|
214
|
+
|
|
215
|
+
await admin.firestore()
|
|
216
|
+
.doc(`marketing-prune-logs/${brand.id}/runs/${logKey}`)
|
|
217
|
+
.set({
|
|
218
|
+
brandId: brand.id,
|
|
219
|
+
date: now.toISOString(),
|
|
220
|
+
count: emails.length,
|
|
221
|
+
emails,
|
|
222
|
+
skippedPaid,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
assistant.log(`Marketing prune: Logged ${emails.length} pruned emails to Firestore (${logKey})`);
|
|
226
|
+
} catch (e) {
|
|
227
|
+
assistant.error('Marketing prune: Failed to write Firestore log:', e.message);
|
|
228
|
+
}
|
|
229
|
+
} finally {
|
|
230
|
+
await tempPrune.cleanup();
|
|
139
231
|
}
|
|
140
232
|
}
|
|
@@ -2,11 +2,11 @@ WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
|
|
|
2
2
|
WARNING: sun.misc.Unsafe::objectFieldOffset has been called by akka.util.Unsafe (file:/Users/ian/.cache/firebase/emulators/firebase-database-emulator-v4.11.2.jar)
|
|
3
3
|
WARNING: Please consider reporting this to the maintainers of class akka.util.Unsafe
|
|
4
4
|
WARNING: sun.misc.Unsafe::objectFieldOffset will be removed in a future release
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
04:14:42.031 [NamespaceSystem-akka.actor.default-dispatcher-4] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
|
|
6
|
+
04:14:42.131 [main] INFO com.firebase.server.forge.App$ - Listening at 127.0.0.1:9000
|
|
7
|
+
04:14:51.750 [NamespaceSystem-akka.actor.default-dispatcher-4] INFO com.firebase.core.namespace.NamespaceActor - demo-backend-manager-default-rtdb successfully activated FBKV (SurveyIdle(0)) wait: 75ms, init: 0ms
|
|
8
|
+
04:14:51.778 [NamespaceSystem-blocking-namespace-operation-dispatcher-6] INFO com.firebase.core.namespace.StateManager - Namespace demo-backend-manager-default-rtdb status Active to Active
|
|
9
|
+
04:15:02.979 [Thread-0] INFO com.firebase.server.forge.App$ - Attempting graceful shutdown.
|
|
10
|
+
04:15:03.025 [NamespaceSystem-akka.actor.default-dispatcher-7] INFO com.firebase.core.namespace.Terminator$Terminator - 1 actors left to terminate: demo-backend-manager-default-rtdb
|
|
11
|
+
04:15:03.028 [NamespaceSystem-akka.actor.default-dispatcher-5] INFO com.firebase.core.namespace.NamespaceActor - stopped namespace actor for demo-backend-manager-default-rtdb
|
|
12
|
+
04:15:03.034 [Thread-0] INFO com.firebase.server.forge.App$ - Graceful shutdown complete.
|
|
@@ -2,7 +2,7 @@ WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
|
|
|
2
2
|
WARNING: sun.misc.Unsafe::allocateMemory has been called by io.netty.util.internal.PlatformDependent0$2 (file:/Users/ian/.cache/firebase/emulators/cloud-firestore-emulator-v1.21.0.jar)
|
|
3
3
|
WARNING: Please consider reporting this to the maintainers of class io.netty.util.internal.PlatformDependent0$2
|
|
4
4
|
WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release
|
|
5
|
-
Jun 27, 2026
|
|
5
|
+
Jun 27, 2026 4:14:40 AM com.google.cloud.datastore.emulator.firestore.websocket.WebSocketServer start
|
|
6
6
|
INFO: Started WebSocket server on ws://127.0.0.1:9150
|
|
7
7
|
|
|
8
8
|
API endpoint: http://127.0.0.1:8080
|
|
@@ -20,117 +20,105 @@ If you are running a Firestore in Datastore Mode project, run:
|
|
|
20
20
|
Note: Support for Datastore Mode is in preview. If you encounter any bugs please file at https://github.com/firebase/firebase-tools/issues.
|
|
21
21
|
Dev App Server is now running.
|
|
22
22
|
|
|
23
|
-
Jun 27, 2026
|
|
23
|
+
Jun 27, 2026 4:14:51 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
24
24
|
INFO: Detected non-HTTP/2 connection.
|
|
25
|
-
Jun 27, 2026
|
|
25
|
+
Jun 27, 2026 4:14:51 AM io.grpc.netty.TcpMetrics loadEpollInfo
|
|
26
26
|
INFO: Epoll available during static init of TcpMetrics:false
|
|
27
|
-
Jun 27, 2026
|
|
27
|
+
Jun 27, 2026 4:14:51 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
28
28
|
INFO: Detected HTTP/2 connection.
|
|
29
|
-
Jun 27, 2026
|
|
29
|
+
Jun 27, 2026 4:14:52 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
30
30
|
INFO: Detected HTTP/2 connection.
|
|
31
|
-
Jun 27, 2026
|
|
31
|
+
Jun 27, 2026 4:14:53 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
32
32
|
INFO: Detected HTTP/2 connection.
|
|
33
|
-
Jun 27, 2026
|
|
33
|
+
Jun 27, 2026 4:15:00 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
34
34
|
INFO: Detected HTTP/2 connection.
|
|
35
|
-
Jun 27, 2026
|
|
35
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
36
36
|
INFO: Detected HTTP/2 connection.
|
|
37
|
-
Jun 27, 2026
|
|
37
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
38
38
|
INFO: Detected HTTP/2 connection.
|
|
39
|
-
Jun 27, 2026
|
|
39
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
40
40
|
INFO: Detected HTTP/2 connection.
|
|
41
|
-
Jun 27, 2026
|
|
41
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
42
42
|
INFO: Detected HTTP/2 connection.
|
|
43
|
-
Jun 27, 2026
|
|
43
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
44
44
|
INFO: Detected HTTP/2 connection.
|
|
45
|
-
Jun 27, 2026
|
|
45
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
46
46
|
INFO: Detected HTTP/2 connection.
|
|
47
|
-
Jun 27, 2026
|
|
47
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
48
48
|
INFO: Detected HTTP/2 connection.
|
|
49
|
-
Jun 27, 2026
|
|
49
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
50
50
|
INFO: Detected HTTP/2 connection.
|
|
51
|
-
Jun 27, 2026
|
|
51
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
52
52
|
INFO: Detected HTTP/2 connection.
|
|
53
|
-
Jun 27, 2026
|
|
53
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
54
54
|
INFO: Detected HTTP/2 connection.
|
|
55
|
-
Jun 27, 2026
|
|
55
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
56
56
|
INFO: Detected HTTP/2 connection.
|
|
57
|
-
Jun 27, 2026
|
|
57
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
58
58
|
INFO: Detected HTTP/2 connection.
|
|
59
|
-
Jun 27, 2026
|
|
59
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
60
60
|
INFO: Detected HTTP/2 connection.
|
|
61
|
-
Jun 27, 2026
|
|
61
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
62
62
|
INFO: Detected HTTP/2 connection.
|
|
63
|
-
Jun 27, 2026
|
|
63
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
64
64
|
INFO: Detected HTTP/2 connection.
|
|
65
|
-
Jun 27, 2026
|
|
65
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
66
66
|
INFO: Detected HTTP/2 connection.
|
|
67
|
-
Jun 27, 2026
|
|
67
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
68
68
|
INFO: Detected HTTP/2 connection.
|
|
69
|
-
Jun 27, 2026
|
|
69
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
70
70
|
INFO: Detected HTTP/2 connection.
|
|
71
|
-
Jun 27, 2026
|
|
71
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
72
72
|
INFO: Detected HTTP/2 connection.
|
|
73
|
-
Jun 27, 2026
|
|
73
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
74
74
|
INFO: Detected HTTP/2 connection.
|
|
75
|
-
Jun 27, 2026
|
|
75
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
76
76
|
INFO: Detected HTTP/2 connection.
|
|
77
|
-
Jun 27, 2026
|
|
77
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
78
78
|
INFO: Detected HTTP/2 connection.
|
|
79
|
-
Jun 27, 2026
|
|
79
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
80
80
|
INFO: Detected HTTP/2 connection.
|
|
81
|
-
Jun 27, 2026
|
|
81
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
82
82
|
INFO: Detected HTTP/2 connection.
|
|
83
|
-
Jun 27, 2026
|
|
83
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
84
84
|
INFO: Detected HTTP/2 connection.
|
|
85
|
-
Jun 27, 2026
|
|
85
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
86
86
|
INFO: Detected HTTP/2 connection.
|
|
87
|
-
Jun 27, 2026
|
|
87
|
+
Jun 27, 2026 4:15:01 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
88
88
|
INFO: Detected HTTP/2 connection.
|
|
89
|
-
Jun 27, 2026
|
|
89
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
90
90
|
INFO: Detected HTTP/2 connection.
|
|
91
|
-
Jun 27, 2026
|
|
91
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
92
92
|
INFO: Detected HTTP/2 connection.
|
|
93
|
-
Jun 27, 2026
|
|
93
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
94
94
|
INFO: Detected HTTP/2 connection.
|
|
95
|
-
Jun 27, 2026
|
|
95
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
96
96
|
INFO: Detected HTTP/2 connection.
|
|
97
|
-
Jun 27, 2026
|
|
97
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
98
98
|
INFO: Detected HTTP/2 connection.
|
|
99
|
-
Jun 27, 2026
|
|
99
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
100
100
|
INFO: Detected HTTP/2 connection.
|
|
101
|
-
Jun 27, 2026
|
|
101
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
102
102
|
INFO: Detected HTTP/2 connection.
|
|
103
|
-
Jun 27, 2026
|
|
103
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
104
104
|
INFO: Detected HTTP/2 connection.
|
|
105
|
-
Jun 27, 2026
|
|
105
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
106
106
|
INFO: Detected HTTP/2 connection.
|
|
107
|
-
Jun 27, 2026
|
|
107
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
108
108
|
INFO: Detected HTTP/2 connection.
|
|
109
|
-
Jun 27, 2026
|
|
109
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
110
110
|
INFO: Detected HTTP/2 connection.
|
|
111
|
-
Jun 27, 2026
|
|
111
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
112
112
|
INFO: Detected HTTP/2 connection.
|
|
113
|
-
Jun 27, 2026
|
|
113
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
114
114
|
INFO: Detected HTTP/2 connection.
|
|
115
|
-
Jun 27, 2026
|
|
115
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
116
116
|
INFO: Detected HTTP/2 connection.
|
|
117
|
-
Jun 27, 2026
|
|
117
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
118
118
|
INFO: Detected HTTP/2 connection.
|
|
119
|
-
Jun 27, 2026
|
|
119
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
120
120
|
INFO: Detected HTTP/2 connection.
|
|
121
|
-
Jun 27, 2026
|
|
122
|
-
INFO: Detected HTTP/2 connection.
|
|
123
|
-
Jun 27, 2026 2:40:04 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
124
|
-
INFO: Detected HTTP/2 connection.
|
|
125
|
-
Jun 27, 2026 2:40:04 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
126
|
-
INFO: Detected HTTP/2 connection.
|
|
127
|
-
Jun 27, 2026 2:40:04 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
128
|
-
INFO: Detected HTTP/2 connection.
|
|
129
|
-
Jun 27, 2026 2:40:04 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
130
|
-
INFO: Detected HTTP/2 connection.
|
|
131
|
-
Jun 27, 2026 2:40:04 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
132
|
-
INFO: Detected HTTP/2 connection.
|
|
133
|
-
Jun 27, 2026 2:40:05 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
121
|
+
Jun 27, 2026 4:15:02 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
134
122
|
INFO: Detected HTTP/2 connection.
|
|
135
123
|
*** shutting down gRPC server since JVM is shutting down
|
|
136
124
|
*** server shut down
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
This is the Google Pub/Sub fake.
|
|
2
2
|
Implementation may be incomplete or differ from the real system.
|
|
3
|
-
Jun 27, 2026
|
|
3
|
+
Jun 27, 2026 4:14:45 AM com.google.cloud.pubsub.testing.v1.Main main
|
|
4
4
|
INFO: IAM integration is disabled. IAM policy methods and ACL checks are not supported
|
|
5
5
|
SLF4J(W): No SLF4J providers were found.
|
|
6
6
|
SLF4J(W): Defaulting to no-operation (NOP) logger implementation
|
|
@@ -9,9 +9,9 @@ WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
|
|
|
9
9
|
WARNING: sun.misc.Unsafe::allocateMemory has been called by io.netty.util.internal.PlatformDependent0$2 (file:/Users/ian/.cache/firebase/emulators/pubsub-emulator-0.8.33/pubsub-emulator/lib/cloud-pubsub-emulator-0.8.33-all.jar)
|
|
10
10
|
WARNING: Please consider reporting this to the maintainers of class io.netty.util.internal.PlatformDependent0$2
|
|
11
11
|
WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release
|
|
12
|
-
Jun 27, 2026
|
|
12
|
+
Jun 27, 2026 4:14:45 AM com.google.cloud.pubsub.testing.v1.Main main
|
|
13
13
|
INFO: Server started, listening on 8085
|
|
14
|
-
Jun 27, 2026
|
|
14
|
+
Jun 27, 2026 4:14:51 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
|
|
15
15
|
INFO: Detected HTTP/2 connection.
|
|
16
16
|
*** shutting down gRPC server since JVM is shutting down
|
|
17
17
|
*** server shut down
|