@lde/pipeline 0.48.0 → 0.50.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.
@@ -1,5 +1,4 @@
1
1
  import { Dataset } from '@lde/dataset';
2
- import type { HostLimiter } from '@lde/host-limiter';
3
2
  import type { Quad } from '@rdfjs/types';
4
3
  import type { DatasetSelector } from './selector.js';
5
4
  import { Stage } from './stage.js';
@@ -120,18 +119,6 @@ export interface PipelineOptions<Out = Quad> {
120
119
  * once per dataset so state resets between datasets.
121
120
  */
122
121
  timeout?: () => TimeoutPolicy;
123
- /**
124
- * The limiter every stage’s readers run their queries on, keyed on the
125
- * endpoint ({@link endpointKeyOf}). Each endpoint’s limit adapts to how it
126
- * responds, up to the limiter’s per-host ceiling, and carries over to the
127
- * next dataset it serves; see {@link SparqlConstructReader}.
128
- *
129
- * Pass the limiter you also give a resolver that loads the same backend –
130
- * keyed on the endpoint too – so the two share one limit.
131
- *
132
- * Left out, the readers share a default: `createHostLimiter(10, 10)`.
133
- */
134
- limiter?: HostLimiter;
135
122
  }
136
123
  export declare class Pipeline<Out = Quad> {
137
124
  private readonly name;
@@ -144,7 +131,13 @@ export declare class Pipeline<Out = Quad> {
144
131
  private readonly chaining?;
145
132
  private readonly reporters;
146
133
  private readonly timeoutFactory;
147
- private readonly limiter?;
134
+ /**
135
+ * The limiter every stage’s readers run their queries on, keyed on the
136
+ * endpoint, so each endpoint’s limit adapts to how it responds and carries
137
+ * over to the next dataset it serves; see {@link SparqlConstructReader}.
138
+ * Its ceiling is the highest `maxConcurrency` of any stage.
139
+ */
140
+ private readonly limiter;
148
141
  private readonly provenanceStore?;
149
142
  private readonly pipelineVersion?;
150
143
  constructor(options: PipelineOptions<Out>);
@@ -155,7 +148,6 @@ export declare class Pipeline<Out = Quad> {
155
148
  /** Persist the processing record for a dataset, when a store is configured. */
156
149
  private recordOutcome;
157
150
  private reportValidators;
158
- private collectStages;
159
151
  /**
160
152
  * The writer a stage's merged output is written through: the open run
161
153
  * wrapped with the plugins' {@link PipelinePlugin.beforeStageWrite}
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAgB,MAAM,cAAc,CAAC;AAMrD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,YAAY,CAAC;AAE5D,OAAO,KAAK,EAKV,MAAM,EACP,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,KAAK,oBAAoB,EAI1B,MAAM,4BAA4B,CAAC;AAKpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAW7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AASpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,2BAA2B,CAAC;AAEnC;;;;;;;;;;;GAWG;AACH,qBAAa,cAAe,SAAQ,KAAK;;CAOxC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAC;IAC1D;;;;;;;;;;;;OAYG;IACH,kBAAkB,CAAC,EAAE,aAAa,CAAC,yBAAyB,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,eAAe,CAAC,GAAG,GAAG,IAAI;IACzC,eAAe,EAAE,eAAe,CAAC;IACjC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;IACrC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,cAAc,EAAE,GAAG,KAAK,CAAC;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,QAAQ,CAAC,EAAE;QACT,mBAAmB,EAAE,mBAAmB,CAAC;QACzC,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,QAAQ,EAAE,CAAC;IAC1C;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,aAAa,CAAC;CAC/B;AA0OD,qBAAa,QAAQ,CAAC,GAAG,GAAG,IAAI;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAyC;IAC3E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAA2C;IAC/E,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAuB;IAC5D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAmC;IAC7D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAsB;IACrD;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAS;gBAE9B,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC;IAgEnC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAyFZ,cAAc;IAgS5B,OAAO,CAAC,MAAM;IAyBd,OAAO,CAAC,iBAAiB;IAczB,+EAA+E;YACjE,aAAa;YAuBb,gBAAgB;IAiB9B;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAgBnB;;;;;;;;OAQG;IACH,OAAO,CAAC,0BAA0B;IA+BlC;;;;;;OAMG;YACW,SAAS;IA0CvB;;;OAGG;YACW,QAAQ;IA+EtB,2EAA2E;YAC7D,eAAe;YAyBf,QAAQ;YAsFP,SAAS;CAczB"}
package/dist/pipeline.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { createReadStream } from 'node:fs';
2
2
  import { randomUUID } from 'node:crypto';
3
+ import { createHostLimiter, positiveIntOrDefault, } from '@lde/host-limiter';
3
4
  import { StreamParser } from 'n3';
4
5
  import { AsyncQueue } from './asyncQueue.js';
5
6
  import { FileWriter } from './writer/fileWriter.js';
@@ -240,6 +241,12 @@ export class Pipeline {
240
241
  chaining;
241
242
  reporters;
242
243
  timeoutFactory;
244
+ /**
245
+ * The limiter every stage’s readers run their queries on, keyed on the
246
+ * endpoint, so each endpoint’s limit adapts to how it responds and carries
247
+ * over to the next dataset it serves; see {@link SparqlConstructReader}.
248
+ * Its ceiling is the highest `maxConcurrency` of any stage.
249
+ */
243
250
  limiter;
244
251
  provenanceStore;
245
252
  pipelineVersion;
@@ -282,7 +289,8 @@ export class Pipeline {
282
289
  this.reporters = [options.reporter ?? []].flat();
283
290
  this.timeoutFactory =
284
291
  options.timeout ?? (() => new ConstantTimeoutPolicy(300_000));
285
- this.limiter = options.limiter;
292
+ const ceiling = positiveIntOrDefault(Math.max(...[...allStages(options.stages)].map((stage) => stage.maxConcurrency)), 10);
293
+ this.limiter = createHostLimiter(ceiling, ceiling);
286
294
  this.provenanceStore = options.provenanceStore;
287
295
  this.pipelineVersion = options.pipelineVersion;
288
296
  }
@@ -491,7 +499,7 @@ export class Pipeline {
491
499
  // completes.
492
500
  let unread;
493
501
  try {
494
- ({ stageFailed, unread } = await this.runStages(dataset, resolved.distribution, timeout, runWriter, context));
502
+ ({ stageFailed, unread } = await this.runStages(dataset, resolved.distribution, sourceKindOf(resolved), timeout, runWriter, context));
495
503
  // Reactive fallback: an endpoint that passed probing but could not serve
496
504
  // the analysis stages is empirically incapable. Switch to the dataset’s
497
505
  // data dump and re-run all stages locally, discarding the
@@ -524,7 +532,7 @@ export class Pipeline {
524
532
  // Discard the endpoint-sourced partial output before the re-run so
525
533
  // the dump-sourced stats replace it rather than appending to it.
526
534
  await runWriter.reset?.(dataset);
527
- ({ stageFailed, unread } = await this.runStages(dataset, fallback.distribution, timeout, runWriter, context));
535
+ ({ stageFailed, unread } = await this.runStages(dataset, fallback.distribution, sourceKindOf(fallback), timeout, runWriter, context));
528
536
  // Adopt the dump’s fingerprint only once the re-run has succeeded.
529
537
  // If the reset or the re-run throws, or a stage fails against the
530
538
  // dump, the dataset is recorded ‘failed’ under the endpoint’s
@@ -637,7 +645,7 @@ export class Pipeline {
637
645
  }
638
646
  async reportValidators(runId, dataset) {
639
647
  const validators = new Set();
640
- for (const stage of this.collectStages(this.stages)) {
648
+ for (const stage of allStages(this.stages)) {
641
649
  if (stage.validator)
642
650
  validators.add(stage.validator);
643
651
  }
@@ -648,13 +656,6 @@ export class Pipeline {
648
656
  }
649
657
  // Walks every stage and sub-stage to collect validators; it reads only
650
658
  // `validator`/`stages`, never output, so it is agnostic to the item type.
651
- *collectStages(stages) {
652
- for (const stage of stages) {
653
- yield stage;
654
- if (stage.stages.length > 0)
655
- yield* this.collectStages(stage.stages);
656
- }
657
- }
658
659
  /**
659
660
  * The writer a stage's merged output is written through: the open run
660
661
  * wrapped with the plugins' {@link PipelinePlugin.beforeStageWrite}
@@ -706,16 +707,16 @@ export class Pipeline {
706
707
  * reacts to – and what the stages could not read, which belongs to this
707
708
  * attempt alone.
708
709
  */
709
- async runStages(dataset, distribution, timeout, runWriter, context) {
710
+ async runStages(dataset, distribution, source, timeout, runWriter, context) {
710
711
  const unread = new UnreadValueTally();
711
712
  let stageFailed = false;
712
713
  for (const stage of this.stages) {
713
714
  try {
714
715
  if (stage.stages.length > 0) {
715
- await this.runChain(dataset, distribution, stage, runWriter, context, timeout);
716
+ await this.runChain(dataset, distribution, source, stage, runWriter, context, timeout);
716
717
  }
717
718
  else {
718
- await this.runStage(context.runId, dataset, distribution, stage, this.stageWriter(runWriter, stage.name), timeout, unread);
719
+ await this.runStage(context.runId, dataset, distribution, stage, this.stageWriter(runWriter, stage.name), source, timeout, unread);
719
720
  }
720
721
  }
721
722
  catch (error) {
@@ -729,13 +730,14 @@ export class Pipeline {
729
730
  * Run a stage with reporting and return whether it was supported.
730
731
  * Returns `true` if the stage produced results, `false` if NotSupported.
731
732
  */
732
- async runStage(runId, dataset, distribution, stage, writer, timeout, unread) {
733
+ async runStage(runId, dataset, distribution, stage, writer, source, timeout, unread) {
733
734
  this.report(runId, { type: 'stageStart', dataset, stage: stage.name });
734
735
  const stageStart = Date.now();
735
736
  let itemsProcessed = 0;
736
737
  let quadsGenerated = 0;
737
738
  let summary;
738
739
  const result = await stage.run(dataset, distribution, writer, {
740
+ source,
739
741
  onProgress: (items, quads) => {
740
742
  itemsProcessed = items;
741
743
  quadsGenerated = quads;
@@ -790,13 +792,13 @@ export class Pipeline {
790
792
  return true;
791
793
  }
792
794
  /** Run a stage in chained mode, throwing if the stage is not supported. */
793
- async runChainedStage(runId, dataset, distribution, stage, writer, timeout) {
794
- const supported = await this.runStage(runId, dataset, distribution, stage, writer, timeout);
795
+ async runChainedStage(runId, dataset, distribution, stage, writer, source, timeout) {
796
+ const supported = await this.runStage(runId, dataset, distribution, stage, writer, source, timeout);
795
797
  if (!supported) {
796
798
  throw new Error(`Stage '${stage.name}' returned NotSupported in chained mode`);
797
799
  }
798
800
  }
799
- async runChain(dataset, distribution, stage, runWriter, context, timeout) {
801
+ async runChain(dataset, distribution, source, stage, runWriter, context, timeout) {
800
802
  const { stageOutputResolver, outputDir } = this.chaining;
801
803
  const outputFiles = [];
802
804
  // Chaining is a quad-only concern: every stage in a chain writes N-Triples
@@ -805,14 +807,14 @@ export class Pipeline {
805
807
  // requirement "sub-stages imply `Out` is `Quad`" is not expressible – `stages`
806
808
  // and `chaining` are independent options – so it is a runtime contract, and
807
809
  // the scratch machinery treats the parent stage as `Stage<Quad>`.
808
- const runScratchStage = async (chainedStage, stageDistribution) => {
810
+ const runScratchStage = async (chainedStage, stageDistribution, stageSource) => {
809
811
  const scratchWriter = new FileWriter({
810
812
  outputDir: `${outputDir}/${chainedStage.name}`,
811
813
  format: 'n-triples',
812
814
  });
813
815
  const scratchRun = await scratchWriter.openRun(context);
814
816
  try {
815
- await this.runChainedStage(context.runId, dataset, stageDistribution, chainedStage, scratchRun, timeout);
817
+ await this.runChainedStage(context.runId, dataset, stageDistribution, chainedStage, scratchRun, stageSource, timeout);
816
818
  await scratchRun.flush(dataset, 'success');
817
819
  await scratchRun.commit();
818
820
  }
@@ -824,12 +826,14 @@ export class Pipeline {
824
826
  };
825
827
  try {
826
828
  // 1. Run parent stage → scratch FileWriter (quad-only, per above).
827
- const parentOutput = await runScratchStage(stage, distribution);
829
+ const parentOutput = await runScratchStage(stage, distribution, source);
828
830
  outputFiles.push(parentOutput);
829
831
  // 2. Chain through children.
830
832
  let currentDistribution = await stageOutputResolver.resolve(parentOutput);
831
833
  for (let i = 0; i < stage.stages.length; i++) {
832
- const childOutput = await runScratchStage(stage.stages[i], currentDistribution);
834
+ // A child reads its parent’s output, which the pipeline serves from
835
+ // a store of its own, as it does an imported dump.
836
+ const childOutput = await runScratchStage(stage.stages[i], currentDistribution, 'imported');
833
837
  outputFiles.push(childOutput);
834
838
  if (i < stage.stages.length - 1) {
835
839
  currentDistribution = await stageOutputResolver.resolve(childOutput);
@@ -861,6 +865,13 @@ export class Pipeline {
861
865
  }
862
866
  }
863
867
  }
868
+ /** Every stage, with the stages chained under it. */
869
+ function* allStages(stages) {
870
+ for (const stage of stages) {
871
+ yield stage;
872
+ yield* allStages(stage.stages);
873
+ }
874
+ }
864
875
  function mapProbeResult(distribution, result) {
865
876
  const fingerprint = sourceFingerprint(distribution, result);
866
877
  if (result instanceof NetworkError) {
@@ -883,3 +894,7 @@ function mapProbeResult(distribution, result) {
883
894
  fingerprint,
884
895
  };
885
896
  }
897
+ /** What kind of source a resolved distribution serves the stages. */
898
+ function sourceKindOf(resolved) {
899
+ return resolved.imported === undefined ? 'endpoint' : 'imported';
900
+ }
@@ -40,12 +40,12 @@ export interface ReadOptions {
40
40
  timeout?: TimeoutPolicy;
41
41
  /**
42
42
  * The limiter every query of a read goes through, keyed on the endpoint
43
- * ({@link endpointKeyOf}), so every dataset an endpoint serves – and
44
- * anything else given that key, such as a resolver fetching from the same
45
- * backend – shares one adaptive limit and one pause. See
43
+ * ({@link endpointKeyOf}), so every read on one endpoint shares one adaptive
44
+ * limit and one pause. A pipeline passes its own. See
46
45
  * {@link SparqlConstructReader}.
47
46
  *
48
- * Reads not given one share a default: `createHostLimiter(10, 10)`.
47
+ * A read not given one gets a limiter for that read alone:
48
+ * `createHostLimiter(10, 10)`. A {@link Stage} passes one for all its batches.
49
49
  */
50
50
  limiter?: HostLimiter;
51
51
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/sparql/reader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/sparql/reader.ts"],"names":[],"mappings":"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"}
@@ -18,8 +18,6 @@ import { classifyOutcome, isTransientError, statusOf } from './failure.js';
18
18
  * matters when the reader is driven directly (without a Pipeline).
19
19
  */
20
20
  const defaultTimeoutPolicy = new ConstantTimeoutPolicy(300_000);
21
- /** The limiter of every read not given one, so they share one limit. */
22
- const defaultLimiter = createHostLimiter(10, 10);
23
21
  /**
24
22
  * A reader could not run because the dataset lacks a supported distribution.
25
23
  */
@@ -129,7 +127,7 @@ export class SparqlConstructReader {
129
127
  const quads = await this.readBatch(bindings, query, {
130
128
  endpoint,
131
129
  key: endpointKeyOf(endpoint),
132
- limiter: options?.limiter ?? defaultLimiter,
130
+ limiter: options?.limiter ?? createHostLimiter(10, 10),
133
131
  policy: options?.timeout ?? defaultTimeoutPolicy,
134
132
  onRootSkipped: (root, error) => {
135
133
  skipped++;
package/dist/stage.d.ts CHANGED
@@ -105,9 +105,19 @@ export interface StageOptions<Out = Quad> {
105
105
  * fills exactly one batch. A `LIMIT` clause in the selector query
106
106
  * overrides this for endpoints with hard result limits.
107
107
  *
108
+ * Give a value per {@link SourceKind} where the two kinds of source want
109
+ * different sizes: an engine that imported a dump for this run alone
110
+ * answers a large batch easily, while a live endpoint shared with others
111
+ * may fail on one. The pipeline tells the stage which kind it reads
112
+ * ({@link RunOptions.source}).
113
+ *
114
+ * ```ts
115
+ * batchSize: { endpoint: 10, imported: 100 }
116
+ * ```
117
+ *
108
118
  * @default 10
109
119
  */
110
- batchSize?: number;
120
+ batchSize?: number | Readonly<Record<SourceKind, number>>;
111
121
  /**
112
122
  * Maximum concurrent in-flight SPARQL queries. Within each batch, all
113
123
  * readers run in parallel; the number of concurrent batches is
@@ -172,8 +182,23 @@ export interface StageOptions<Out = Quad> {
172
182
  onInvalid?: 'write' | 'skip' | 'halt';
173
183
  };
174
184
  }
185
+ /**
186
+ * What a stage reads: a live SPARQL `endpoint` the dataset publishes, or a
187
+ * data dump the pipeline `imported` into a store of its own for the run.
188
+ */
189
+ export type SourceKind = 'endpoint' | 'imported';
175
190
  export interface RunOptions extends Pick<ReadOptions, 'limiter' | 'onRootSkipped'> {
176
191
  onProgress?: (itemsProcessed: number, quadsGenerated: number) => void;
192
+ /**
193
+ * What the distribution handed to {@link Stage.run} serves, which picks the
194
+ * {@link StageOptions.batchSize} of a stage that gives one per kind. A stage
195
+ * whose {@link StageOptions.sourceFor} substitutes another distribution reads
196
+ * a source the pipeline did not resolve, so it reads that as an `endpoint`
197
+ * whatever this says.
198
+ *
199
+ * @default 'endpoint'
200
+ */
201
+ source?: SourceKind;
177
202
  /**
178
203
  * Per-dataset {@link TimeoutPolicy} threaded through to readers and
179
204
  * item selectors. The Pipeline owns lifecycle (factory invocation per
@@ -201,10 +226,13 @@ export declare class Stage<Out = Quad> {
201
226
  /** Whether this stage reads a source of its own rather than the dataset’s
202
227
  * resolved distribution. @see {@link StageOptions.sourceFor} */
203
228
  readonly sourcesOwnData: boolean;
229
+ /** Maximum concurrent in-flight SPARQL queries. @see {@link StageOptions.maxConcurrency} */
230
+ readonly maxConcurrency: number;
204
231
  private readonly readers;
205
232
  private readonly itemSelector?;
206
233
  private readonly batchSize;
207
- private readonly maxConcurrency;
234
+ /** The limiter of a run not given one, so its batches back off together. */
235
+ private readonly limiter;
208
236
  private readonly validation?;
209
237
  private readonly project?;
210
238
  private readonly queueCapacity?;
@@ -1 +1 @@
1
- {"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../src/stage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stage.d.ts","sourceRoot":"","sources":["../src/stage.ts"],"names":[],"mappings":"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"}
package/dist/stage.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createHostLimiter, positiveIntOrDefault, } from '@lde/host-limiter';
1
2
  import { NoItemsSelected, NotSupported } from './sparql/reader.js';
2
3
  import { batch } from './batch.js';
3
4
  import { AsyncQueue } from './asyncQueue.js';
@@ -10,10 +11,13 @@ export class Stage {
10
11
  /** Whether this stage reads a source of its own rather than the dataset’s
11
12
  * resolved distribution. @see {@link StageOptions.sourceFor} */
12
13
  sourcesOwnData;
14
+ /** Maximum concurrent in-flight SPARQL queries. @see {@link StageOptions.maxConcurrency} */
15
+ maxConcurrency;
13
16
  readers;
14
17
  itemSelector;
15
18
  batchSize;
16
- maxConcurrency;
19
+ /** The limiter of a run not given one, so its batches back off together. */
20
+ limiter;
17
21
  validation;
18
22
  project;
19
23
  queueCapacity;
@@ -39,6 +43,8 @@ export class Stage {
39
43
  this.itemSelector = options.itemSelector;
40
44
  this.batchSize = options.batchSize ?? 10;
41
45
  this.maxConcurrency = options.maxConcurrency ?? 10;
46
+ const ceiling = positiveIntOrDefault(this.maxConcurrency, 10);
47
+ this.limiter = createHostLimiter(ceiling, ceiling);
42
48
  this.validation = options.validation;
43
49
  this.expectsOutput = options.expectsOutput ?? false;
44
50
  this.project = options.project;
@@ -54,7 +60,7 @@ export class Stage {
54
60
  const timeout = options?.timeout;
55
61
  const readOptions = {
56
62
  timeout,
57
- limiter: options?.limiter,
63
+ limiter: options?.limiter ?? this.limiter,
58
64
  onRootSkipped: options?.onRootSkipped,
59
65
  };
60
66
  // Substituted once, before anything reads: the selector and the readers
@@ -64,9 +70,17 @@ export class Stage {
64
70
  : resolved;
65
71
  const tally = new StageTally(this.transformNames);
66
72
  if (this.itemSelector) {
67
- const result = await this.runWithSelector(tally.selected(this.itemSelector.select(distribution, this.batchSize, {
73
+ // A substituted source is one the pipeline did not resolve; one handed
74
+ // back unchanged is still the source the pipeline resolved.
75
+ const source = distribution === resolved
76
+ ? (options?.source ?? 'endpoint')
77
+ : 'endpoint';
78
+ const batchSize = typeof this.batchSize === 'number'
79
+ ? this.batchSize
80
+ : this.batchSize[source];
81
+ const result = await this.runWithSelector(tally.selected(this.itemSelector.select(distribution, batchSize, {
68
82
  timeout,
69
- })), dataset, distribution, writer, tally, readOptions, options);
83
+ })), batchSize, dataset, distribution, writer, tally, readOptions, options);
70
84
  if (!(result instanceof NotSupported)) {
71
85
  options?.onComplete?.(tally.summary());
72
86
  }
@@ -138,10 +152,10 @@ export class Stage {
138
152
  throw new Error(`Stage '${this.name}' expected output but produced none`);
139
153
  }
140
154
  }
141
- async runWithSelector(selector, dataset, distribution, writer, tally, readOptions, options) {
155
+ async runWithSelector(selector, batchSize, dataset, distribution, writer, tally, readOptions, options) {
142
156
  // Peek the first batch to detect an empty selector before starting the
143
157
  // writer (important because e.g. SparqlUpdateWriter does CLEAR GRAPH).
144
- const batches = batch(selector, this.batchSize);
158
+ const batches = batch(selector, batchSize);
145
159
  const iter = batches[Symbol.asyncIterator]();
146
160
  const first = await iter.next();
147
161
  if (first.done) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lde/pipeline",
3
- "version": "0.48.0",
3
+ "version": "0.50.0",
4
4
  "repository": {
5
5
  "url": "git+https://github.com/ldelements/lde.git",
6
6
  "directory": "packages/pipeline"