@gigzen/populace 1.1.0 → 1.2.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gigzen/populace",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "A simulated population that uses your app through its real API, so you can test what needs more than one person.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.mjs CHANGED
@@ -264,9 +264,24 @@ async function run() {
264
264
 
265
265
  console.log(`\n Bringing ${agents} people to life across ${cities.join(", ")}…\n`);
266
266
 
267
+ // Sign-ups are counted here rather than in the engine, so the engine keeps
268
+ // knowing nothing about who is watching.
269
+ let joinedSoFar = 0;
267
270
  const world = World.fromConfig(config, adapter, {
268
- joined: (a) => console.log(` ✓ ${a.persona.name} (${a.persona.city.name}, ${a.persona.platform})`),
269
- joinFailed: (p, e) => console.log(` ${p.name}: ${e.message}`),
271
+ joined: (a) => {
272
+ console.log(` ${a.persona.name} (${a.persona.city.name}, ${a.persona.platform})`);
273
+ progress.joining({
274
+ done: ++joinedSoFar, total: agents, ok: true,
275
+ name: a.persona.name, city: a.persona.city.name,
276
+ });
277
+ },
278
+ joinFailed: (p, e) => {
279
+ console.log(` ✖ ${p.name}: ${e.message}`);
280
+ progress.joining({
281
+ done: ++joinedSoFar, total: agents, ok: false,
282
+ name: p.name, city: p.city?.name,
283
+ });
284
+ },
270
285
  // Said out loud, because waiting silently is indistinguishable from hanging.
271
286
  // Retrying a throttled sign-up can add seconds per person, and a run that
272
287
  // pauses without explanation is a run somebody kills.
package/src/progress.mjs CHANGED
@@ -71,7 +71,7 @@ function latencies(metrics) {
71
71
  * @param {(line: string) => void} options.write
72
72
  */
73
73
  export function createProgress({ enabled, everyLatency = 5, write = (l) => process.stdout.write(l) } = {}) {
74
- if (!enabled) return { start() {}, tick() {}, done() {} };
74
+ if (!enabled) return { start() {}, joining() {}, tick() {}, done() {} };
75
75
 
76
76
  const emit = (event) => {
77
77
  try {
@@ -97,6 +97,18 @@ export function createProgress({ enabled, everyLatency = 5, write = (l) => proce
97
97
  });
98
98
  },
99
99
 
100
+ /**
101
+ * One event per person as they sign in, before any tick exists.
102
+ *
103
+ * Signing 250 people in takes minutes, and until this existed a watcher had
104
+ * nothing to show for it: every counter read zero, the progress bar stayed
105
+ * empty and the clock counted down as though the run were already under way.
106
+ * A window that looks identical to a hung one is a window people kill.
107
+ */
108
+ joining({ done, total, name, city, ok }) {
109
+ emit({ type: "joining", done, total, name, city, ok });
110
+ },
111
+
100
112
  tick(tickNo, totalTicks, world, metrics) {
101
113
  const t = world.totals();
102
114
  emit({