@fluidframework/agent-scheduler 0.59.2000 → 0.59.3000-67119

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/.eslintrc.js CHANGED
@@ -12,6 +12,5 @@ module.exports = {
12
12
  },
13
13
  "rules": {
14
14
  "@typescript-eslint/strict-boolean-expressions": "off",
15
- "no-null/no-null": "off"
16
15
  }
17
16
  }
package/README.md CHANGED
@@ -16,8 +16,7 @@ protected async initializingFirstTime() {
16
16
  }
17
17
 
18
18
  // When creating your DataObjectFactory
19
- export const MyDataObjectFactory = new DataObjectFactory
20
- (
19
+ export const MyDataObjectFactory = new DataObjectFactory(
21
20
  "my-data-object",
22
21
  MyDataObject,
23
22
  [],
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAE5E,eAAO,MAAM,eAAe,EAAE,MAAM,sBAA0C,CAAC;AAE/E,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC7C;AAED,MAAM,WAAW,qBAAsB,SAAQ,MAAM;IACjD;;;;;;;;;;;;OAYG;IACH,CAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,OAAC;CAC9E;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,sBAAsB,EAAE,cAAc,CAAC,qBAAqB,CAAC;IAClG;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C;;;;;;;OAOG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;;;;;OAKG;IACH,OAAO,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE,CAAC;CAC3B"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAE5E,eAAO,MAAM,eAAe,EAAE,MAAM,sBAA0C,CAAC;AAE/E,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC7C;AAED,MAAM,WAAW,qBAAsB,SAAQ,MAAM;IACjD;;;;;;;;;;;;OAYG;IACH,CAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,OAAE;CAC/E;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,sBAAsB,EAAE,cAAc,CAAC,qBAAqB,CAAC;IAClG;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C;;;;;;;OAOG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;;;;;OAKG;IACH,OAAO,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE,CAAC;CAC3B"}
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIU,QAAA,eAAe,GAAiC,iBAAiB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IEvent, IEventProvider } from \"@fluidframework/common-definitions\";\n\nexport const IAgentScheduler: keyof IProvideAgentScheduler = \"IAgentScheduler\";\n\nexport interface IProvideAgentScheduler {\n readonly IAgentScheduler: IAgentScheduler;\n}\n\nexport interface IAgentSchedulerEvents extends IEvent {\n /**\n * Event when ownership of task changes\n * @param event - name of the event:\n * \"picked\" - the task has been assigned to this client, in response to pick() being called\n * If client loses this task (due to disconnect), it will attempt to pick it again (on connection)\n * automatically, unless release() is called\n * \"released\" - the task was successfully released back to the pool. Client will not attempt to\n * re-acquire the task, unless pick() is called.\n * \"lost\" - task is lost due to disconnect or data store / container being attached.\n * Task will be picked up again by some connected client (this client will try as well,\n * unless release() is called)\n * @param listener - callback notified when change happened for particular key\n */\n (event: \"picked\" | \"released\" | \"lost\", listener: (taskId: string) => void)\n}\n\n/**\n * Agent scheduler distributes a set of tasks/variables across connected clients.\n */\nexport interface IAgentScheduler extends IProvideAgentScheduler, IEventProvider<IAgentSchedulerEvents> {\n /**\n * Registers a set of new tasks to distribute amongst connected clients. Only use this if a client wants\n * a new agent to run but does not have the capability to run the agent inside the host.\n * Client can call pick() later if the capability changes.\n *\n * This method should only be called once per task. Duplicate calls will be rejected.\n */\n register(...taskUrls: string[]): Promise<void>;\n\n /**\n * Attempts to pick a set of tasks. A client will only run the task if it's chosen based on consensus.\n * Resolves when the tasks are assigned to one of the connected clients.\n *\n * This method should only be called once per task. Duplicate calls will be rejected.\n *\n * @param worker - callback to run when task is picked up.\n */\n pick(taskId: string, worker: () => Promise<void>): Promise<void>;\n\n /**\n * Releases a set of tasks for other clients to grab. Resolves when the tasks are released.\n *\n * Only previously picked tasks are allowed. Releasing non picked tasks will get a rejection.\n * App can call pickedTasks() to get the picked list first.\n */\n release(...taskUrls: string[]): Promise<void>;\n\n /**\n * Returns a list of all tasks running on this client\n */\n pickedTasks(): string[];\n}\n"]}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIU,QAAA,eAAe,GAAiC,iBAAiB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IEvent, IEventProvider } from \"@fluidframework/common-definitions\";\n\nexport const IAgentScheduler: keyof IProvideAgentScheduler = \"IAgentScheduler\";\n\nexport interface IProvideAgentScheduler {\n readonly IAgentScheduler: IAgentScheduler;\n}\n\nexport interface IAgentSchedulerEvents extends IEvent {\n /**\n * Event when ownership of task changes\n * @param event - name of the event:\n * \"picked\" - the task has been assigned to this client, in response to pick() being called\n * If client loses this task (due to disconnect), it will attempt to pick it again (on connection)\n * automatically, unless release() is called\n * \"released\" - the task was successfully released back to the pool. Client will not attempt to\n * re-acquire the task, unless pick() is called.\n * \"lost\" - task is lost due to disconnect or data store / container being attached.\n * Task will be picked up again by some connected client (this client will try as well,\n * unless release() is called)\n * @param listener - callback notified when change happened for particular key\n */\n (event: \"picked\" | \"released\" | \"lost\", listener: (taskId: string) => void);\n}\n\n/**\n * Agent scheduler distributes a set of tasks/variables across connected clients.\n */\nexport interface IAgentScheduler extends IProvideAgentScheduler, IEventProvider<IAgentSchedulerEvents> {\n /**\n * Registers a set of new tasks to distribute amongst connected clients. Only use this if a client wants\n * a new agent to run but does not have the capability to run the agent inside the host.\n * Client can call pick() later if the capability changes.\n *\n * This method should only be called once per task. Duplicate calls will be rejected.\n */\n register(...taskUrls: string[]): Promise<void>;\n\n /**\n * Attempts to pick a set of tasks. A client will only run the task if it's chosen based on consensus.\n * Resolves when the tasks are assigned to one of the connected clients.\n *\n * This method should only be called once per task. Duplicate calls will be rejected.\n *\n * @param worker - callback to run when task is picked up.\n */\n pick(taskId: string, worker: () => Promise<void>): Promise<void>;\n\n /**\n * Releases a set of tasks for other clients to grab. Resolves when the tasks are released.\n *\n * Only previously picked tasks are allowed. Releasing non picked tasks will get a rejection.\n * App can call pickedTasks() to get the picked list first.\n */\n release(...taskUrls: string[]): Promise<void>;\n\n /**\n * Returns a list of all tasks running on this client\n */\n pickedTasks(): string[];\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAU,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EACH,YAAY,EACZ,QAAQ,EACX,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACH,qBAAqB,EAErB,qBAAqB,EACxB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAmB,MAAM,uCAAuC,CAAC;AAChG,OAAO,EACH,sBAAsB,EACtB,sBAAsB,EACtB,gCAAgC,EACnC,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AA4BjE,qBAAa,cAAe,SAAQ,iBAAiB,CAAC,qBAAqB,CAAE,YAAW,eAAe;IAmD/F,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,2BAA2B;WApD5B,IAAI,CAAC,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO;IAqB5G,IAAW,eAAe,SAAmB;IAE7C,OAAO,KAAK,QAAQ,GAOnB;IAMD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IAKrD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA0C;IAI/E,OAAO,CAAC,YAAY,CAAqB;IAEzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAGxB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,2BAA2B,EAAE,2BAA2B,CAAC,MAAM,GAAG,IAAI,CAAC;IAM5F,IAAW,MAAM,uBAEhB;IAEY,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB9C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBhE,OAAO,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnD,WAAW,IAAI,MAAM,EAAE;YAIhB,YAAY;YAkBZ,WAAW;YAYX,UAAU;IASxB,OAAO,CAAC,eAAe;YAIT,SAAS;IAIvB,OAAO,CAAC,UAAU;IAiElB,OAAO,CAAC,iBAAiB;YAeX,gBAAgB;IAuB9B,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,cAAc;CAGzB;AAED,cAAM,qBAAsB,SAAQ,qBAAqB;IACrD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;gBAEtD,gBAAgB,EAAE,sBAAsB,EACxC,oBAAoB,EAAE,qBAAqB,EAC3C,QAAQ,EAAE,OAAO;IAKR,OAAO,CAAC,OAAO,EAAE,QAAQ;CAUzC;AAED,qBAAa,qBAAsB,YAAW,sBAAsB;IAChE,gBAAuB,IAAI,gBAAgB;IAC3C,SAAgB,IAAI,gBAA8B;IAElD,IAAW,sBAAsB,SAAmB;IAEpD,WAAkB,aAAa,IAAI,gCAAgC,CAElE;WAEmB,mBAAmB,CAAC,aAAa,EAAE,sBAAsB,GAAG,OAAO,CAAC,cAAc,CAAC;IAM1F,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO;CASvF"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAU,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EACH,YAAY,EACZ,QAAQ,EACX,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACH,qBAAqB,EAErB,qBAAqB,EACxB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAmB,MAAM,uCAAuC,CAAC;AAChG,OAAO,EACH,sBAAsB,EACtB,sBAAsB,EACtB,gCAAgC,EACnC,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AA4BjE,qBAAa,cAAe,SAAQ,iBAAiB,CAAC,qBAAqB,CAAE,YAAW,eAAe;IAmD/F,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,2BAA2B;WApD5B,IAAI,CAAC,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO;IAqB5G,IAAW,eAAe,SAAmB;IAE7C,OAAO,KAAK,QAAQ,GAOnB;IAMD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IAKrD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA0C;IAI/E,OAAO,CAAC,YAAY,CAAqB;IAEzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAGxB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,2BAA2B,EAAE,2BAA2B,CAAC,MAAM,GAAG,IAAI,CAAC;IAM5F,IAAW,MAAM,uBAEhB;IAEY,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB9C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBhE,OAAO,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnD,WAAW,IAAI,MAAM,EAAE;YAIhB,YAAY;YAkBZ,WAAW;YAYX,UAAU;IASxB,OAAO,CAAC,eAAe;YAIT,SAAS;IAIvB,OAAO,CAAC,UAAU;IAiElB,OAAO,CAAC,iBAAiB;YAcX,gBAAgB;IAyB9B,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,cAAc;CAGzB;AAED,cAAM,qBAAsB,SAAQ,qBAAqB;IACrD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;gBAEtD,gBAAgB,EAAE,sBAAsB,EACxC,oBAAoB,EAAE,qBAAqB,EAC3C,QAAQ,EAAE,OAAO;IAKR,OAAO,CAAC,OAAO,EAAE,QAAQ;CAUzC;AAED,qBAAa,qBAAsB,YAAW,sBAAsB;IAChE,gBAAuB,IAAI,gBAAgB;IAC3C,SAAgB,IAAI,gBAA8B;IAElD,IAAW,sBAAsB,SAAmB;IAEpD,WAAkB,aAAa,IAAI,gCAAgC,CAElE;WAEmB,mBAAmB,CAAC,aAAa,EAAE,sBAAsB,GAAG,OAAO,CAAC,cAAc,CAAC;IAM1F,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO;CASvF"}
package/dist/scheduler.js CHANGED
@@ -13,7 +13,7 @@ const register_collection_1 = require("@fluidframework/register-collection");
13
13
  const runtime_utils_1 = require("@fluidframework/runtime-utils");
14
14
  const uuid_1 = require("uuid");
15
15
  // Note: making sure this ID is unique and does not collide with storage provided clientID
16
- const UnattachedClientId = `${uuid_1.v4()}_unattached`;
16
+ const UnattachedClientId = `${(0, uuid_1.v4)()}_unattached`;
17
17
  const mapWait = async (map, key) => {
18
18
  const maybeValue = map.get(key);
19
19
  if (maybeValue !== undefined) {
@@ -67,7 +67,7 @@ class AgentScheduler extends common_utils_1.TypedEventEmitter {
67
67
  else {
68
68
  root = await runtime.getChannel("root");
69
69
  const handle = await mapWait(root, schedulerId);
70
- common_utils_1.assert(handle !== undefined, 0x116 /* "Missing handle on scheduler load" */);
70
+ (0, common_utils_1.assert)(handle !== undefined, 0x116 /* "Missing handle on scheduler load" */);
71
71
  consensusRegisterCollection = await handle.get();
72
72
  }
73
73
  const agentScheduler = new AgentScheduler(runtime, context, consensusRegisterCollection);
@@ -80,7 +80,7 @@ class AgentScheduler extends common_utils_1.TypedEventEmitter {
80
80
  return UnattachedClientId;
81
81
  }
82
82
  const clientId = this.runtime.clientId;
83
- common_utils_1.assert(!!clientId, 0x117 /* "Trying to get missing clientId!" */);
83
+ (0, common_utils_1.assert)(!!clientId, 0x117 /* "Trying to get missing clientId!" */);
84
84
  return clientId;
85
85
  }
86
86
  get handle() {
@@ -111,7 +111,7 @@ class AgentScheduler extends common_utils_1.TypedEventEmitter {
111
111
  // We have a policy to disallow non-interactive clients from taking tasks. Callers of pick() can
112
112
  // either perform this check proactively and call conditionally, or catch the error (in which case
113
113
  // they can know they will not get the task).
114
- common_utils_1.assert(this.context.deltaManager.clientDetails.capabilities.interactive, 0x118 /* "Bad client interactive check" */);
114
+ (0, common_utils_1.assert)(this.context.deltaManager.clientDetails.capabilities.interactive, 0x118 /* "Bad client interactive check" */);
115
115
  // Check the current status and express interest if it's a new one (undefined) or currently unpicked (null).
116
116
  if (this.isActive()) {
117
117
  const currentClient = this.getTaskClientId(taskId);
@@ -128,7 +128,7 @@ class AgentScheduler extends common_utils_1.TypedEventEmitter {
128
128
  }
129
129
  // Note - the assumption is - we are connected.
130
130
  // If not - all tasks should have been dropped already on disconnect / attachment
131
- common_utils_1.assert(active, 0x119 /* "This agent became inactive while releasing" */);
131
+ (0, common_utils_1.assert)(active, 0x119 /* "This agent became inactive while releasing" */);
132
132
  if (this.getTaskClientId(taskUrl) !== this.clientId) {
133
133
  throw new Error(`${taskUrl} was never picked`);
134
134
  }
@@ -149,7 +149,7 @@ class AgentScheduler extends common_utils_1.TypedEventEmitter {
149
149
  for (const taskUrl of taskUrls) {
150
150
  const taskStatus = this.getTaskClientId(taskUrl);
151
151
  // Task should be either registered (null) or picked up.
152
- common_utils_1.assert(taskStatus !== undefined, 0x11a /* `Unsuccessful registration` */);
152
+ (0, common_utils_1.assert)(taskStatus !== undefined, 0x11a /* `Unsuccessful registration` */);
153
153
  }
154
154
  }
155
155
  }
@@ -165,7 +165,7 @@ class AgentScheduler extends common_utils_1.TypedEventEmitter {
165
165
  }
166
166
  }
167
167
  async clearTasks(taskUrls) {
168
- common_utils_1.assert(this.isActive(), 0x11b /* "Trying to clear tasks on inactive agent" */);
168
+ (0, common_utils_1.assert)(this.isActive(), 0x11b /* "Trying to clear tasks on inactive agent" */);
169
169
  const clearP = [];
170
170
  for (const taskUrl of taskUrls) {
171
171
  clearP.push(this.writeCore(taskUrl, null));
@@ -185,7 +185,7 @@ class AgentScheduler extends common_utils_1.TypedEventEmitter {
185
185
  // Probably okay for now to have every client try to do this.
186
186
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
187
187
  quorum.on("removeMember", async (clientId) => {
188
- common_utils_1.assert(this.runtime.objectsRoutingContext.isAttached, 0x11c /* "Detached object routing context" */);
188
+ (0, common_utils_1.assert)(this.runtime.objectsRoutingContext.isAttached, 0x11c /* "Detached object routing context" */);
189
189
  // Cleanup only if connected. If not, cleanup will happen in initializeCore() that runs on connection.
190
190
  if (this.isActive()) {
191
191
  const tasks = [];
@@ -240,7 +240,7 @@ class AgentScheduler extends common_utils_1.TypedEventEmitter {
240
240
  });
241
241
  }
242
242
  onNewTaskAssigned(key) {
243
- common_utils_1.assert(!this.runningTasks.has(key), 0x11d /* "task is already running" */);
243
+ (0, common_utils_1.assert)(!this.runningTasks.has(key), 0x11d /* "task is already running" */);
244
244
  this.runningTasks.add(key);
245
245
  const worker = this.locallyRunnableTasks.get(key);
246
246
  if (worker === undefined) {
@@ -258,7 +258,8 @@ class AgentScheduler extends common_utils_1.TypedEventEmitter {
258
258
  this.runningTasks.delete(key);
259
259
  this.emit("released", key);
260
260
  }
261
- common_utils_1.assert(currentClient !== undefined, 0x11e /* "client is undefined" */);
261
+ (0, common_utils_1.assert)(currentClient !== undefined, 0x11e /* "client is undefined" */);
262
+ /* eslint-disable @typescript-eslint/brace-style */
262
263
  if (this.isActive()) {
263
264
  // attempt to pick up task if we are connected.
264
265
  // If not, initializeCore() will do it when connected
@@ -274,6 +275,7 @@ class AgentScheduler extends common_utils_1.TypedEventEmitter {
274
275
  await this.writeCore(key, null);
275
276
  }
276
277
  }
278
+ /* eslint-enable @typescript-eslint/brace-style */
277
279
  }
278
280
  isActive() {
279
281
  // Scheduler should be active in detached container.
@@ -352,7 +354,7 @@ class AgentSchedulerFactory {
352
354
  static async createChildInstance(parentContext) {
353
355
  const packagePath = [...parentContext.packagePath, AgentSchedulerFactory.type];
354
356
  const router = await parentContext.containerRuntime.createDataStore(packagePath);
355
- return runtime_utils_1.requestFluidObject(router, "/");
357
+ return (0, runtime_utils_1.requestFluidObject)(router, "/");
356
358
  }
357
359
  async instantiateDataStore(context, existing) {
358
360
  const mapFactory = map_1.SharedMap.getFactory();
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IFluidHandle,\n IRequest,\n} from \"@fluidframework/core-interfaces\";\nimport {\n FluidDataStoreRuntime,\n FluidObjectHandle,\n ISharedObjectRegistry,\n} from \"@fluidframework/datastore\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ISharedMap, IValueChanged, SharedMap } from \"@fluidframework/map\";\nimport { ConsensusRegisterCollection } from \"@fluidframework/register-collection\";\nimport { IFluidDataStoreRuntime, IChannelFactory } from \"@fluidframework/datastore-definitions\";\nimport {\n IFluidDataStoreContext,\n IFluidDataStoreFactory,\n NamedFluidDataStoreRegistryEntry,\n} from \"@fluidframework/runtime-definitions\";\nimport { requestFluidObject } from \"@fluidframework/runtime-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport { IAgentScheduler, IAgentSchedulerEvents } from \"./agent\";\n\n// Note: making sure this ID is unique and does not collide with storage provided clientID\nconst UnattachedClientId = `${uuid()}_unattached`;\n\nconst mapWait = async <T = any>(map: ISharedMap, key: string): Promise<T> => {\n const maybeValue = map.get<T>(key);\n if (maybeValue !== undefined) {\n return maybeValue;\n }\n\n return new Promise((resolve) => {\n const handler = (changed: IValueChanged) => {\n if (changed.key === key) {\n map.off(\"valueChanged\", handler);\n const value = map.get<T>(changed.key);\n if (value === undefined) {\n throw new Error(\"Unexpected valueChanged result\");\n }\n resolve(value);\n }\n };\n map.on(\"valueChanged\", handler);\n });\n};\n\nconst schedulerId = \"scheduler\";\n\nexport class AgentScheduler extends TypedEventEmitter<IAgentSchedulerEvents> implements IAgentScheduler {\n public static async load(runtime: IFluidDataStoreRuntime, context: IFluidDataStoreContext, existing: boolean) {\n let root: ISharedMap;\n let consensusRegisterCollection: ConsensusRegisterCollection<string | null>;\n if (!existing) {\n root = SharedMap.create(runtime, \"root\");\n root.bindToContext();\n consensusRegisterCollection = ConsensusRegisterCollection.create(runtime);\n consensusRegisterCollection.bindToContext();\n root.set(schedulerId, consensusRegisterCollection.handle);\n } else {\n root = await runtime.getChannel(\"root\") as ISharedMap;\n const handle = await mapWait<IFluidHandle<ConsensusRegisterCollection<string | null>>>(root, schedulerId);\n assert(handle !== undefined, 0x116 /* \"Missing handle on scheduler load\" */);\n consensusRegisterCollection = await handle.get();\n }\n const agentScheduler = new AgentScheduler(runtime, context, consensusRegisterCollection);\n agentScheduler.initialize();\n\n return agentScheduler;\n }\n\n public get IAgentScheduler() { return this; }\n\n private get clientId(): string {\n if (this.runtime.attachState === AttachState.Detached) {\n return UnattachedClientId;\n }\n const clientId = this.runtime.clientId;\n assert(!!clientId, 0x117 /* \"Trying to get missing clientId!\" */);\n return clientId;\n }\n\n // Set of tasks registered by this client.\n // Has no relationship with lists below.\n // The only requirement here - a task can be registered by a client only once.\n // Other clients can pick these tasks.\n private readonly registeredTasks = new Set<string>();\n\n // List of all tasks client is capable of running (essentially expressed desire to run)\n // Client will proactively attempt to pick them up these tasks if they are not assigned to other clients.\n // This is a strict superset of tasks running in the client.\n private readonly locallyRunnableTasks = new Map<string, () => Promise<void>>();\n\n // Set of registered tasks client is currently running.\n // It's subset of this.locallyRunnableTasks\n private runningTasks = new Set<string>();\n\n private readonly _handle: IFluidHandle<this>;\n\n constructor(\n private readonly runtime: IFluidDataStoreRuntime,\n private readonly context: IFluidDataStoreContext,\n private readonly consensusRegisterCollection: ConsensusRegisterCollection<string | null>,\n ) {\n super();\n this._handle = new FluidObjectHandle(this, \"\", this.runtime.objectsRoutingContext);\n }\n\n public get handle() {\n return this._handle;\n }\n\n public async register(...taskUrls: string[]): Promise<void> {\n for (const taskUrl of taskUrls) {\n if (this.registeredTasks.has(taskUrl)) {\n throw new Error(`${taskUrl} is already registered`);\n }\n }\n const unregisteredTasks: string[] = [];\n for (const taskUrl of taskUrls) {\n this.registeredTasks.add(taskUrl);\n // Only register for a new task.\n const currentClient = this.getTaskClientId(taskUrl);\n if (currentClient === undefined) {\n unregisteredTasks.push(taskUrl);\n }\n }\n return this.registerCore(unregisteredTasks);\n }\n\n public async pick(taskId: string, worker: () => Promise<void>): Promise<void> {\n if (this.locallyRunnableTasks.has(taskId)) {\n throw new Error(`${taskId} is already attempted`);\n }\n this.locallyRunnableTasks.set(taskId, worker);\n\n // We have a policy to disallow non-interactive clients from taking tasks. Callers of pick() can\n // either perform this check proactively and call conditionally, or catch the error (in which case\n // they can know they will not get the task).\n assert(this.context.deltaManager.clientDetails.capabilities.interactive,\n 0x118 /* \"Bad client interactive check\" */);\n\n // Check the current status and express interest if it's a new one (undefined) or currently unpicked (null).\n if (this.isActive()) {\n const currentClient = this.getTaskClientId(taskId);\n if (currentClient === undefined || currentClient === null) {\n await this.writeCore(taskId, this.clientId);\n }\n }\n }\n\n public async release(...taskUrls: string[]): Promise<void> {\n const active = this.isActive();\n for (const taskUrl of taskUrls) {\n if (!this.locallyRunnableTasks.has(taskUrl)) {\n throw new Error(`${taskUrl} was never registered`);\n }\n // Note - the assumption is - we are connected.\n // If not - all tasks should have been dropped already on disconnect / attachment\n assert(active, 0x119 /* \"This agent became inactive while releasing\" */);\n if (this.getTaskClientId(taskUrl) !== this.clientId) {\n throw new Error(`${taskUrl} was never picked`);\n }\n }\n return this.releaseCore([...taskUrls]);\n }\n\n public pickedTasks(): string[] {\n return Array.from(this.runningTasks.values());\n }\n\n private async registerCore(taskUrls: string[]): Promise<void> {\n if (taskUrls.length > 0) {\n const registersP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n registersP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(registersP);\n\n // The registers should have up to date results now. Check the status.\n for (const taskUrl of taskUrls) {\n const taskStatus = this.getTaskClientId(taskUrl);\n\n // Task should be either registered (null) or picked up.\n assert(taskStatus !== undefined, 0x11a /* `Unsuccessful registration` */);\n }\n }\n }\n\n private async releaseCore(taskUrls: string[]) {\n if (taskUrls.length > 0) {\n const releasesP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n // Remove from local map so that it can be picked later.\n this.locallyRunnableTasks.delete(taskUrl);\n releasesP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(releasesP);\n }\n }\n\n private async clearTasks(taskUrls: string[]) {\n assert(this.isActive(), 0x11b /* \"Trying to clear tasks on inactive agent\" */);\n const clearP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n clearP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(clearP);\n }\n\n private getTaskClientId(url: string): string | null | undefined {\n return this.consensusRegisterCollection.read(url);\n }\n\n private async writeCore(key: string, clientId: string | null): Promise<void> {\n await this.consensusRegisterCollection.write(key, clientId);\n }\n\n private initialize() {\n const quorum = this.runtime.getQuorum();\n // A client left the quorum. Iterate and clear tasks held by that client.\n // Ideally a leader should do this cleanup. But it's complicated when a leader itself leaves.\n // Probably okay for now to have every client try to do this.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n quorum.on(\"removeMember\", async (clientId: string) => {\n assert(this.runtime.objectsRoutingContext.isAttached, 0x11c /* \"Detached object routing context\" */);\n // Cleanup only if connected. If not, cleanup will happen in initializeCore() that runs on connection.\n if (this.isActive()) {\n const tasks: Promise<any>[] = [];\n const leftTasks: string[] = [];\n for (const taskUrl of this.consensusRegisterCollection.keys()) {\n if (this.getTaskClientId(taskUrl) === clientId) {\n if (this.locallyRunnableTasks.has(taskUrl)) {\n tasks.push(this.writeCore(taskUrl, this.clientId));\n } else {\n leftTasks.push(taskUrl);\n }\n }\n }\n tasks.push(this.clearTasks(leftTasks));\n await Promise.all(tasks).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_RemoveMemberError\", error);\n });\n }\n });\n\n // Listeners for new/released tasks. All clients will try to grab at the same time.\n // May be we want a randomized timer (Something like raft) to reduce chattiness?\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.consensusRegisterCollection.on(\"atomicChanged\", async (key: string, currentClient: string | null) => {\n // Check if this client was chosen.\n if (this.isActive() && currentClient === this.clientId) {\n this.onNewTaskAssigned(key);\n } else {\n await this.onTaskReassigned(key, currentClient);\n }\n });\n\n if (this.isActive()) {\n this.initializeCore();\n }\n\n this.runtime.on(\"connected\", () => {\n if (this.isActive()) {\n this.initializeCore();\n }\n });\n\n if (this.runtime.attachState === AttachState.Detached) {\n this.runtime.waitAttached().then(() => {\n this.clearRunningTasks();\n }).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_clearRunningTasks\", error);\n });\n }\n\n this.runtime.on(\"disconnected\", () => {\n if (this.runtime.attachState !== AttachState.Detached) {\n this.clearRunningTasks();\n }\n });\n }\n\n private onNewTaskAssigned(key: string) {\n assert(!this.runningTasks.has(key), 0x11d /* \"task is already running\" */);\n this.runningTasks.add(key);\n const worker = this.locallyRunnableTasks.get(key);\n if (worker === undefined) {\n this.sendErrorEvent(\"AgentScheduler_UnwantedChange\", undefined, key);\n }\n else {\n this.emit(\"picked\", key);\n worker().catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_FailedWork\", error, key);\n });\n }\n }\n\n private async onTaskReassigned(key: string, currentClient: string | null) {\n if (this.runningTasks.has(key)) {\n this.runningTasks.delete(key);\n this.emit(\"released\", key);\n }\n assert(currentClient !== undefined, 0x11e /* \"client is undefined\" */);\n if (this.isActive()) {\n // attempt to pick up task if we are connected.\n // If not, initializeCore() will do it when connected\n if (currentClient === null) {\n if (this.locallyRunnableTasks.has(key)) {\n await this.writeCore(key, this.clientId);\n }\n }\n // Check if the op came from dropped client\n // This could happen when \"old\" ops are submitted on reconnection.\n // They carry \"old\" ref seq number, but if write is not contested, it will get accepted\n else if (this.runtime.getQuorum().getMember(currentClient) === undefined) {\n await this.writeCore(key, null);\n }\n }\n }\n\n private isActive() {\n // Scheduler should be active in detached container.\n if (this.runtime.attachState === AttachState.Detached) {\n return true;\n }\n if (!this.runtime.connected) {\n return false;\n }\n\n // Note: we are not checking for this.context.deltaManager.clientDetails.capabilities.interactive\n // here. Instead we assert in pick() if a non-interactive client tries to pick.\n\n return this.context.deltaManager.active;\n }\n\n private initializeCore() {\n // Nobody released the tasks held by last client in previous session.\n // Check to see if this client needs to do this.\n const clearCandidates: string[] = [];\n const tasks: Promise<any>[] = [];\n\n for (const [taskUrl] of this.locallyRunnableTasks) {\n if (!this.getTaskClientId(taskUrl)) {\n tasks.push(this.writeCore(taskUrl, this.clientId));\n }\n }\n\n for (const taskUrl of this.consensusRegisterCollection.keys()) {\n const currentClient = this.getTaskClientId(taskUrl);\n if (currentClient && this.runtime.getQuorum().getMember(currentClient) === undefined) {\n clearCandidates.push(taskUrl);\n }\n }\n\n tasks.push(this.clearTasks(clearCandidates));\n\n Promise.all(tasks).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_InitError\", error);\n });\n }\n\n private clearRunningTasks() {\n const tasks = this.runningTasks;\n this.runningTasks = new Set<string>();\n\n if (this.isActive()) {\n // Clear all tasks with UnattachedClientId (if was unattached) and reapply for tasks with new clientId\n // If we are simply disconnected, then proper cleanup will be done on connection.\n this.initializeCore();\n }\n\n for (const task of tasks) {\n this.emit(\"lost\", task);\n }\n }\n\n private sendErrorEvent(eventName: string, error: any, key?: string) {\n this.runtime.logger.sendErrorEvent({ eventName, key }, error);\n }\n}\n\nclass AgentSchedulerRuntime extends FluidDataStoreRuntime {\n private readonly agentSchedulerP: Promise<AgentScheduler>;\n constructor(\n dataStoreContext: IFluidDataStoreContext,\n sharedObjectRegistry: ISharedObjectRegistry,\n existing: boolean,\n ) {\n super(dataStoreContext, sharedObjectRegistry, existing);\n this.agentSchedulerP = AgentScheduler.load(this, dataStoreContext, existing);\n }\n public async request(request: IRequest) {\n const response = await super.request(request);\n if (response.status === 404) {\n if (request.url === \"\" || request.url === \"/\") {\n const agentScheduler = await this.agentSchedulerP;\n return { status: 200, mimeType: \"fluid/object\", value: agentScheduler };\n }\n }\n return response;\n }\n}\n\nexport class AgentSchedulerFactory implements IFluidDataStoreFactory {\n public static readonly type = \"_scheduler\";\n public readonly type = AgentSchedulerFactory.type;\n\n public get IFluidDataStoreFactory() { return this; }\n\n public static get registryEntry(): NamedFluidDataStoreRegistryEntry {\n return [this.type, Promise.resolve(new AgentSchedulerFactory())];\n }\n\n public static async createChildInstance(parentContext: IFluidDataStoreContext): Promise<AgentScheduler> {\n const packagePath = [...parentContext.packagePath, AgentSchedulerFactory.type];\n const router = await parentContext.containerRuntime.createDataStore(packagePath);\n return requestFluidObject<AgentScheduler>(router, \"/\");\n }\n\n public async instantiateDataStore(context: IFluidDataStoreContext, existing: boolean) {\n const mapFactory = SharedMap.getFactory();\n const consensusRegisterCollectionFactory = ConsensusRegisterCollection.getFactory();\n const dataTypes = new Map<string, IChannelFactory>();\n dataTypes.set(mapFactory.type, mapFactory);\n dataTypes.set(consensusRegisterCollectionFactory.type, consensusRegisterCollectionFactory);\n\n return new AgentSchedulerRuntime(context, dataTypes, existing);\n }\n}\n"]}
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IFluidHandle,\n IRequest,\n} from \"@fluidframework/core-interfaces\";\nimport {\n FluidDataStoreRuntime,\n FluidObjectHandle,\n ISharedObjectRegistry,\n} from \"@fluidframework/datastore\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ISharedMap, IValueChanged, SharedMap } from \"@fluidframework/map\";\nimport { ConsensusRegisterCollection } from \"@fluidframework/register-collection\";\nimport { IFluidDataStoreRuntime, IChannelFactory } from \"@fluidframework/datastore-definitions\";\nimport {\n IFluidDataStoreContext,\n IFluidDataStoreFactory,\n NamedFluidDataStoreRegistryEntry,\n} from \"@fluidframework/runtime-definitions\";\nimport { requestFluidObject } from \"@fluidframework/runtime-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport { IAgentScheduler, IAgentSchedulerEvents } from \"./agent\";\n\n// Note: making sure this ID is unique and does not collide with storage provided clientID\nconst UnattachedClientId = `${uuid()}_unattached`;\n\nconst mapWait = async <T = any>(map: ISharedMap, key: string): Promise<T> => {\n const maybeValue = map.get<T>(key);\n if (maybeValue !== undefined) {\n return maybeValue;\n }\n\n return new Promise((resolve) => {\n const handler = (changed: IValueChanged) => {\n if (changed.key === key) {\n map.off(\"valueChanged\", handler);\n const value = map.get<T>(changed.key);\n if (value === undefined) {\n throw new Error(\"Unexpected valueChanged result\");\n }\n resolve(value);\n }\n };\n map.on(\"valueChanged\", handler);\n });\n};\n\nconst schedulerId = \"scheduler\";\n\nexport class AgentScheduler extends TypedEventEmitter<IAgentSchedulerEvents> implements IAgentScheduler {\n public static async load(runtime: IFluidDataStoreRuntime, context: IFluidDataStoreContext, existing: boolean) {\n let root: ISharedMap;\n let consensusRegisterCollection: ConsensusRegisterCollection<string | null>;\n if (!existing) {\n root = SharedMap.create(runtime, \"root\");\n root.bindToContext();\n consensusRegisterCollection = ConsensusRegisterCollection.create(runtime);\n consensusRegisterCollection.bindToContext();\n root.set(schedulerId, consensusRegisterCollection.handle);\n } else {\n root = await runtime.getChannel(\"root\") as ISharedMap;\n const handle = await mapWait<IFluidHandle<ConsensusRegisterCollection<string | null>>>(root, schedulerId);\n assert(handle !== undefined, 0x116 /* \"Missing handle on scheduler load\" */);\n consensusRegisterCollection = await handle.get();\n }\n const agentScheduler = new AgentScheduler(runtime, context, consensusRegisterCollection);\n agentScheduler.initialize();\n\n return agentScheduler;\n }\n\n public get IAgentScheduler() { return this; }\n\n private get clientId(): string {\n if (this.runtime.attachState === AttachState.Detached) {\n return UnattachedClientId;\n }\n const clientId = this.runtime.clientId;\n assert(!!clientId, 0x117 /* \"Trying to get missing clientId!\" */);\n return clientId;\n }\n\n // Set of tasks registered by this client.\n // Has no relationship with lists below.\n // The only requirement here - a task can be registered by a client only once.\n // Other clients can pick these tasks.\n private readonly registeredTasks = new Set<string>();\n\n // List of all tasks client is capable of running (essentially expressed desire to run)\n // Client will proactively attempt to pick them up these tasks if they are not assigned to other clients.\n // This is a strict superset of tasks running in the client.\n private readonly locallyRunnableTasks = new Map<string, () => Promise<void>>();\n\n // Set of registered tasks client is currently running.\n // It's subset of this.locallyRunnableTasks\n private runningTasks = new Set<string>();\n\n private readonly _handle: IFluidHandle<this>;\n\n constructor(\n private readonly runtime: IFluidDataStoreRuntime,\n private readonly context: IFluidDataStoreContext,\n private readonly consensusRegisterCollection: ConsensusRegisterCollection<string | null>,\n ) {\n super();\n this._handle = new FluidObjectHandle(this, \"\", this.runtime.objectsRoutingContext);\n }\n\n public get handle() {\n return this._handle;\n }\n\n public async register(...taskUrls: string[]): Promise<void> {\n for (const taskUrl of taskUrls) {\n if (this.registeredTasks.has(taskUrl)) {\n throw new Error(`${taskUrl} is already registered`);\n }\n }\n const unregisteredTasks: string[] = [];\n for (const taskUrl of taskUrls) {\n this.registeredTasks.add(taskUrl);\n // Only register for a new task.\n const currentClient = this.getTaskClientId(taskUrl);\n if (currentClient === undefined) {\n unregisteredTasks.push(taskUrl);\n }\n }\n return this.registerCore(unregisteredTasks);\n }\n\n public async pick(taskId: string, worker: () => Promise<void>): Promise<void> {\n if (this.locallyRunnableTasks.has(taskId)) {\n throw new Error(`${taskId} is already attempted`);\n }\n this.locallyRunnableTasks.set(taskId, worker);\n\n // We have a policy to disallow non-interactive clients from taking tasks. Callers of pick() can\n // either perform this check proactively and call conditionally, or catch the error (in which case\n // they can know they will not get the task).\n assert(this.context.deltaManager.clientDetails.capabilities.interactive,\n 0x118 /* \"Bad client interactive check\" */);\n\n // Check the current status and express interest if it's a new one (undefined) or currently unpicked (null).\n if (this.isActive()) {\n const currentClient = this.getTaskClientId(taskId);\n if (currentClient === undefined || currentClient === null) {\n await this.writeCore(taskId, this.clientId);\n }\n }\n }\n\n public async release(...taskUrls: string[]): Promise<void> {\n const active = this.isActive();\n for (const taskUrl of taskUrls) {\n if (!this.locallyRunnableTasks.has(taskUrl)) {\n throw new Error(`${taskUrl} was never registered`);\n }\n // Note - the assumption is - we are connected.\n // If not - all tasks should have been dropped already on disconnect / attachment\n assert(active, 0x119 /* \"This agent became inactive while releasing\" */);\n if (this.getTaskClientId(taskUrl) !== this.clientId) {\n throw new Error(`${taskUrl} was never picked`);\n }\n }\n return this.releaseCore([...taskUrls]);\n }\n\n public pickedTasks(): string[] {\n return Array.from(this.runningTasks.values());\n }\n\n private async registerCore(taskUrls: string[]): Promise<void> {\n if (taskUrls.length > 0) {\n const registersP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n registersP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(registersP);\n\n // The registers should have up to date results now. Check the status.\n for (const taskUrl of taskUrls) {\n const taskStatus = this.getTaskClientId(taskUrl);\n\n // Task should be either registered (null) or picked up.\n assert(taskStatus !== undefined, 0x11a /* `Unsuccessful registration` */);\n }\n }\n }\n\n private async releaseCore(taskUrls: string[]) {\n if (taskUrls.length > 0) {\n const releasesP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n // Remove from local map so that it can be picked later.\n this.locallyRunnableTasks.delete(taskUrl);\n releasesP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(releasesP);\n }\n }\n\n private async clearTasks(taskUrls: string[]) {\n assert(this.isActive(), 0x11b /* \"Trying to clear tasks on inactive agent\" */);\n const clearP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n clearP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(clearP);\n }\n\n private getTaskClientId(url: string): string | null | undefined {\n return this.consensusRegisterCollection.read(url);\n }\n\n private async writeCore(key: string, clientId: string | null): Promise<void> {\n await this.consensusRegisterCollection.write(key, clientId);\n }\n\n private initialize() {\n const quorum = this.runtime.getQuorum();\n // A client left the quorum. Iterate and clear tasks held by that client.\n // Ideally a leader should do this cleanup. But it's complicated when a leader itself leaves.\n // Probably okay for now to have every client try to do this.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n quorum.on(\"removeMember\", async (clientId: string) => {\n assert(this.runtime.objectsRoutingContext.isAttached, 0x11c /* \"Detached object routing context\" */);\n // Cleanup only if connected. If not, cleanup will happen in initializeCore() that runs on connection.\n if (this.isActive()) {\n const tasks: Promise<any>[] = [];\n const leftTasks: string[] = [];\n for (const taskUrl of this.consensusRegisterCollection.keys()) {\n if (this.getTaskClientId(taskUrl) === clientId) {\n if (this.locallyRunnableTasks.has(taskUrl)) {\n tasks.push(this.writeCore(taskUrl, this.clientId));\n } else {\n leftTasks.push(taskUrl);\n }\n }\n }\n tasks.push(this.clearTasks(leftTasks));\n await Promise.all(tasks).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_RemoveMemberError\", error);\n });\n }\n });\n\n // Listeners for new/released tasks. All clients will try to grab at the same time.\n // May be we want a randomized timer (Something like raft) to reduce chattiness?\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.consensusRegisterCollection.on(\"atomicChanged\", async (key: string, currentClient: string | null) => {\n // Check if this client was chosen.\n if (this.isActive() && currentClient === this.clientId) {\n this.onNewTaskAssigned(key);\n } else {\n await this.onTaskReassigned(key, currentClient);\n }\n });\n\n if (this.isActive()) {\n this.initializeCore();\n }\n\n this.runtime.on(\"connected\", () => {\n if (this.isActive()) {\n this.initializeCore();\n }\n });\n\n if (this.runtime.attachState === AttachState.Detached) {\n this.runtime.waitAttached().then(() => {\n this.clearRunningTasks();\n }).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_clearRunningTasks\", error);\n });\n }\n\n this.runtime.on(\"disconnected\", () => {\n if (this.runtime.attachState !== AttachState.Detached) {\n this.clearRunningTasks();\n }\n });\n }\n\n private onNewTaskAssigned(key: string) {\n assert(!this.runningTasks.has(key), 0x11d /* \"task is already running\" */);\n this.runningTasks.add(key);\n const worker = this.locallyRunnableTasks.get(key);\n if (worker === undefined) {\n this.sendErrorEvent(\"AgentScheduler_UnwantedChange\", undefined, key);\n } else {\n this.emit(\"picked\", key);\n worker().catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_FailedWork\", error, key);\n });\n }\n }\n\n private async onTaskReassigned(key: string, currentClient: string | null) {\n if (this.runningTasks.has(key)) {\n this.runningTasks.delete(key);\n this.emit(\"released\", key);\n }\n assert(currentClient !== undefined, 0x11e /* \"client is undefined\" */);\n /* eslint-disable @typescript-eslint/brace-style */\n if (this.isActive()) {\n // attempt to pick up task if we are connected.\n // If not, initializeCore() will do it when connected\n if (currentClient === null) {\n if (this.locallyRunnableTasks.has(key)) {\n await this.writeCore(key, this.clientId);\n }\n }\n // Check if the op came from dropped client\n // This could happen when \"old\" ops are submitted on reconnection.\n // They carry \"old\" ref seq number, but if write is not contested, it will get accepted\n else if (this.runtime.getQuorum().getMember(currentClient) === undefined) {\n await this.writeCore(key, null);\n }\n }\n /* eslint-enable @typescript-eslint/brace-style */\n }\n\n private isActive() {\n // Scheduler should be active in detached container.\n if (this.runtime.attachState === AttachState.Detached) {\n return true;\n }\n if (!this.runtime.connected) {\n return false;\n }\n\n // Note: we are not checking for this.context.deltaManager.clientDetails.capabilities.interactive\n // here. Instead we assert in pick() if a non-interactive client tries to pick.\n\n return this.context.deltaManager.active;\n }\n\n private initializeCore() {\n // Nobody released the tasks held by last client in previous session.\n // Check to see if this client needs to do this.\n const clearCandidates: string[] = [];\n const tasks: Promise<any>[] = [];\n\n for (const [taskUrl] of this.locallyRunnableTasks) {\n if (!this.getTaskClientId(taskUrl)) {\n tasks.push(this.writeCore(taskUrl, this.clientId));\n }\n }\n\n for (const taskUrl of this.consensusRegisterCollection.keys()) {\n const currentClient = this.getTaskClientId(taskUrl);\n if (currentClient && this.runtime.getQuorum().getMember(currentClient) === undefined) {\n clearCandidates.push(taskUrl);\n }\n }\n\n tasks.push(this.clearTasks(clearCandidates));\n\n Promise.all(tasks).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_InitError\", error);\n });\n }\n\n private clearRunningTasks() {\n const tasks = this.runningTasks;\n this.runningTasks = new Set<string>();\n\n if (this.isActive()) {\n // Clear all tasks with UnattachedClientId (if was unattached) and reapply for tasks with new clientId\n // If we are simply disconnected, then proper cleanup will be done on connection.\n this.initializeCore();\n }\n\n for (const task of tasks) {\n this.emit(\"lost\", task);\n }\n }\n\n private sendErrorEvent(eventName: string, error: any, key?: string) {\n this.runtime.logger.sendErrorEvent({ eventName, key }, error);\n }\n}\n\nclass AgentSchedulerRuntime extends FluidDataStoreRuntime {\n private readonly agentSchedulerP: Promise<AgentScheduler>;\n constructor(\n dataStoreContext: IFluidDataStoreContext,\n sharedObjectRegistry: ISharedObjectRegistry,\n existing: boolean,\n ) {\n super(dataStoreContext, sharedObjectRegistry, existing);\n this.agentSchedulerP = AgentScheduler.load(this, dataStoreContext, existing);\n }\n public async request(request: IRequest) {\n const response = await super.request(request);\n if (response.status === 404) {\n if (request.url === \"\" || request.url === \"/\") {\n const agentScheduler = await this.agentSchedulerP;\n return { status: 200, mimeType: \"fluid/object\", value: agentScheduler };\n }\n }\n return response;\n }\n}\n\nexport class AgentSchedulerFactory implements IFluidDataStoreFactory {\n public static readonly type = \"_scheduler\";\n public readonly type = AgentSchedulerFactory.type;\n\n public get IFluidDataStoreFactory() { return this; }\n\n public static get registryEntry(): NamedFluidDataStoreRegistryEntry {\n return [this.type, Promise.resolve(new AgentSchedulerFactory())];\n }\n\n public static async createChildInstance(parentContext: IFluidDataStoreContext): Promise<AgentScheduler> {\n const packagePath = [...parentContext.packagePath, AgentSchedulerFactory.type];\n const router = await parentContext.containerRuntime.createDataStore(packagePath);\n return requestFluidObject<AgentScheduler>(router, \"/\");\n }\n\n public async instantiateDataStore(context: IFluidDataStoreContext, existing: boolean) {\n const mapFactory = SharedMap.getFactory();\n const consensusRegisterCollectionFactory = ConsensusRegisterCollection.getFactory();\n const dataTypes = new Map<string, IChannelFactory>();\n dataTypes.set(mapFactory.type, mapFactory);\n dataTypes.set(consensusRegisterCollectionFactory.type, consensusRegisterCollectionFactory);\n\n return new AgentSchedulerRuntime(context, dataTypes, existing);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAE5E,eAAO,MAAM,eAAe,EAAE,MAAM,sBAA0C,CAAC;AAE/E,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC7C;AAED,MAAM,WAAW,qBAAsB,SAAQ,MAAM;IACjD;;;;;;;;;;;;OAYG;IACH,CAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,OAAC;CAC9E;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,sBAAsB,EAAE,cAAc,CAAC,qBAAqB,CAAC;IAClG;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C;;;;;;;OAOG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;;;;;OAKG;IACH,OAAO,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE,CAAC;CAC3B"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAE5E,eAAO,MAAM,eAAe,EAAE,MAAM,sBAA0C,CAAC;AAE/E,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC7C;AAED,MAAM,WAAW,qBAAsB,SAAQ,MAAM;IACjD;;;;;;;;;;;;OAYG;IACH,CAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,OAAE;CAC/E;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,sBAAsB,EAAE,cAAc,CAAC,qBAAqB,CAAC;IAClG;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C;;;;;;;OAOG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE;;;;;OAKG;IACH,OAAO,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE,CAAC;CAC3B"}
package/lib/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,CAAC,MAAM,eAAe,GAAiC,iBAAiB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IEvent, IEventProvider } from \"@fluidframework/common-definitions\";\n\nexport const IAgentScheduler: keyof IProvideAgentScheduler = \"IAgentScheduler\";\n\nexport interface IProvideAgentScheduler {\n readonly IAgentScheduler: IAgentScheduler;\n}\n\nexport interface IAgentSchedulerEvents extends IEvent {\n /**\n * Event when ownership of task changes\n * @param event - name of the event:\n * \"picked\" - the task has been assigned to this client, in response to pick() being called\n * If client loses this task (due to disconnect), it will attempt to pick it again (on connection)\n * automatically, unless release() is called\n * \"released\" - the task was successfully released back to the pool. Client will not attempt to\n * re-acquire the task, unless pick() is called.\n * \"lost\" - task is lost due to disconnect or data store / container being attached.\n * Task will be picked up again by some connected client (this client will try as well,\n * unless release() is called)\n * @param listener - callback notified when change happened for particular key\n */\n (event: \"picked\" | \"released\" | \"lost\", listener: (taskId: string) => void)\n}\n\n/**\n * Agent scheduler distributes a set of tasks/variables across connected clients.\n */\nexport interface IAgentScheduler extends IProvideAgentScheduler, IEventProvider<IAgentSchedulerEvents> {\n /**\n * Registers a set of new tasks to distribute amongst connected clients. Only use this if a client wants\n * a new agent to run but does not have the capability to run the agent inside the host.\n * Client can call pick() later if the capability changes.\n *\n * This method should only be called once per task. Duplicate calls will be rejected.\n */\n register(...taskUrls: string[]): Promise<void>;\n\n /**\n * Attempts to pick a set of tasks. A client will only run the task if it's chosen based on consensus.\n * Resolves when the tasks are assigned to one of the connected clients.\n *\n * This method should only be called once per task. Duplicate calls will be rejected.\n *\n * @param worker - callback to run when task is picked up.\n */\n pick(taskId: string, worker: () => Promise<void>): Promise<void>;\n\n /**\n * Releases a set of tasks for other clients to grab. Resolves when the tasks are released.\n *\n * Only previously picked tasks are allowed. Releasing non picked tasks will get a rejection.\n * App can call pickedTasks() to get the picked list first.\n */\n release(...taskUrls: string[]): Promise<void>;\n\n /**\n * Returns a list of all tasks running on this client\n */\n pickedTasks(): string[];\n}\n"]}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,CAAC,MAAM,eAAe,GAAiC,iBAAiB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IEvent, IEventProvider } from \"@fluidframework/common-definitions\";\n\nexport const IAgentScheduler: keyof IProvideAgentScheduler = \"IAgentScheduler\";\n\nexport interface IProvideAgentScheduler {\n readonly IAgentScheduler: IAgentScheduler;\n}\n\nexport interface IAgentSchedulerEvents extends IEvent {\n /**\n * Event when ownership of task changes\n * @param event - name of the event:\n * \"picked\" - the task has been assigned to this client, in response to pick() being called\n * If client loses this task (due to disconnect), it will attempt to pick it again (on connection)\n * automatically, unless release() is called\n * \"released\" - the task was successfully released back to the pool. Client will not attempt to\n * re-acquire the task, unless pick() is called.\n * \"lost\" - task is lost due to disconnect or data store / container being attached.\n * Task will be picked up again by some connected client (this client will try as well,\n * unless release() is called)\n * @param listener - callback notified when change happened for particular key\n */\n (event: \"picked\" | \"released\" | \"lost\", listener: (taskId: string) => void);\n}\n\n/**\n * Agent scheduler distributes a set of tasks/variables across connected clients.\n */\nexport interface IAgentScheduler extends IProvideAgentScheduler, IEventProvider<IAgentSchedulerEvents> {\n /**\n * Registers a set of new tasks to distribute amongst connected clients. Only use this if a client wants\n * a new agent to run but does not have the capability to run the agent inside the host.\n * Client can call pick() later if the capability changes.\n *\n * This method should only be called once per task. Duplicate calls will be rejected.\n */\n register(...taskUrls: string[]): Promise<void>;\n\n /**\n * Attempts to pick a set of tasks. A client will only run the task if it's chosen based on consensus.\n * Resolves when the tasks are assigned to one of the connected clients.\n *\n * This method should only be called once per task. Duplicate calls will be rejected.\n *\n * @param worker - callback to run when task is picked up.\n */\n pick(taskId: string, worker: () => Promise<void>): Promise<void>;\n\n /**\n * Releases a set of tasks for other clients to grab. Resolves when the tasks are released.\n *\n * Only previously picked tasks are allowed. Releasing non picked tasks will get a rejection.\n * App can call pickedTasks() to get the picked list first.\n */\n release(...taskUrls: string[]): Promise<void>;\n\n /**\n * Returns a list of all tasks running on this client\n */\n pickedTasks(): string[];\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAU,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EACH,YAAY,EACZ,QAAQ,EACX,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACH,qBAAqB,EAErB,qBAAqB,EACxB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAmB,MAAM,uCAAuC,CAAC;AAChG,OAAO,EACH,sBAAsB,EACtB,sBAAsB,EACtB,gCAAgC,EACnC,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AA4BjE,qBAAa,cAAe,SAAQ,iBAAiB,CAAC,qBAAqB,CAAE,YAAW,eAAe;IAmD/F,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,2BAA2B;WApD5B,IAAI,CAAC,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO;IAqB5G,IAAW,eAAe,SAAmB;IAE7C,OAAO,KAAK,QAAQ,GAOnB;IAMD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IAKrD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA0C;IAI/E,OAAO,CAAC,YAAY,CAAqB;IAEzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAGxB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,2BAA2B,EAAE,2BAA2B,CAAC,MAAM,GAAG,IAAI,CAAC;IAM5F,IAAW,MAAM,uBAEhB;IAEY,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB9C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBhE,OAAO,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnD,WAAW,IAAI,MAAM,EAAE;YAIhB,YAAY;YAkBZ,WAAW;YAYX,UAAU;IASxB,OAAO,CAAC,eAAe;YAIT,SAAS;IAIvB,OAAO,CAAC,UAAU;IAiElB,OAAO,CAAC,iBAAiB;YAeX,gBAAgB;IAuB9B,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,cAAc;CAGzB;AAED,cAAM,qBAAsB,SAAQ,qBAAqB;IACrD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;gBAEtD,gBAAgB,EAAE,sBAAsB,EACxC,oBAAoB,EAAE,qBAAqB,EAC3C,QAAQ,EAAE,OAAO;IAKR,OAAO,CAAC,OAAO,EAAE,QAAQ;CAUzC;AAED,qBAAa,qBAAsB,YAAW,sBAAsB;IAChE,gBAAuB,IAAI,gBAAgB;IAC3C,SAAgB,IAAI,gBAA8B;IAElD,IAAW,sBAAsB,SAAmB;IAEpD,WAAkB,aAAa,IAAI,gCAAgC,CAElE;WAEmB,mBAAmB,CAAC,aAAa,EAAE,sBAAsB,GAAG,OAAO,CAAC,cAAc,CAAC;IAM1F,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO;CASvF"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAU,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EACH,YAAY,EACZ,QAAQ,EACX,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACH,qBAAqB,EAErB,qBAAqB,EACxB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAmB,MAAM,uCAAuC,CAAC;AAChG,OAAO,EACH,sBAAsB,EACtB,sBAAsB,EACtB,gCAAgC,EACnC,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AA4BjE,qBAAa,cAAe,SAAQ,iBAAiB,CAAC,qBAAqB,CAAE,YAAW,eAAe;IAmD/F,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,2BAA2B;WApD5B,IAAI,CAAC,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO;IAqB5G,IAAW,eAAe,SAAmB;IAE7C,OAAO,KAAK,QAAQ,GAOnB;IAMD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;IAKrD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAA0C;IAI/E,OAAO,CAAC,YAAY,CAAqB;IAEzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAGxB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,sBAAsB,EAC/B,2BAA2B,EAAE,2BAA2B,CAAC,MAAM,GAAG,IAAI,CAAC;IAM5F,IAAW,MAAM,uBAEhB;IAEY,QAAQ,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB9C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBhE,OAAO,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnD,WAAW,IAAI,MAAM,EAAE;YAIhB,YAAY;YAkBZ,WAAW;YAYX,UAAU;IASxB,OAAO,CAAC,eAAe;YAIT,SAAS;IAIvB,OAAO,CAAC,UAAU;IAiElB,OAAO,CAAC,iBAAiB;YAcX,gBAAgB;IAyB9B,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,cAAc;CAGzB;AAED,cAAM,qBAAsB,SAAQ,qBAAqB;IACrD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0B;gBAEtD,gBAAgB,EAAE,sBAAsB,EACxC,oBAAoB,EAAE,qBAAqB,EAC3C,QAAQ,EAAE,OAAO;IAKR,OAAO,CAAC,OAAO,EAAE,QAAQ;CAUzC;AAED,qBAAa,qBAAsB,YAAW,sBAAsB;IAChE,gBAAuB,IAAI,gBAAgB;IAC3C,SAAgB,IAAI,gBAA8B;IAElD,IAAW,sBAAsB,SAAmB;IAEpD,WAAkB,aAAa,IAAI,gCAAgC,CAElE;WAEmB,mBAAmB,CAAC,aAAa,EAAE,sBAAsB,GAAG,OAAO,CAAC,cAAc,CAAC;IAM1F,oBAAoB,CAAC,OAAO,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO;CASvF"}
package/lib/scheduler.js CHANGED
@@ -256,6 +256,7 @@ export class AgentScheduler extends TypedEventEmitter {
256
256
  this.emit("released", key);
257
257
  }
258
258
  assert(currentClient !== undefined, 0x11e /* "client is undefined" */);
259
+ /* eslint-disable @typescript-eslint/brace-style */
259
260
  if (this.isActive()) {
260
261
  // attempt to pick up task if we are connected.
261
262
  // If not, initializeCore() will do it when connected
@@ -271,6 +272,7 @@ export class AgentScheduler extends TypedEventEmitter {
271
272
  await this.writeCore(key, null);
272
273
  }
273
274
  }
275
+ /* eslint-enable @typescript-eslint/brace-style */
274
276
  }
275
277
  isActive() {
276
278
  // Scheduler should be active in detached container.
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IFluidHandle,\n IRequest,\n} from \"@fluidframework/core-interfaces\";\nimport {\n FluidDataStoreRuntime,\n FluidObjectHandle,\n ISharedObjectRegistry,\n} from \"@fluidframework/datastore\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ISharedMap, IValueChanged, SharedMap } from \"@fluidframework/map\";\nimport { ConsensusRegisterCollection } from \"@fluidframework/register-collection\";\nimport { IFluidDataStoreRuntime, IChannelFactory } from \"@fluidframework/datastore-definitions\";\nimport {\n IFluidDataStoreContext,\n IFluidDataStoreFactory,\n NamedFluidDataStoreRegistryEntry,\n} from \"@fluidframework/runtime-definitions\";\nimport { requestFluidObject } from \"@fluidframework/runtime-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport { IAgentScheduler, IAgentSchedulerEvents } from \"./agent\";\n\n// Note: making sure this ID is unique and does not collide with storage provided clientID\nconst UnattachedClientId = `${uuid()}_unattached`;\n\nconst mapWait = async <T = any>(map: ISharedMap, key: string): Promise<T> => {\n const maybeValue = map.get<T>(key);\n if (maybeValue !== undefined) {\n return maybeValue;\n }\n\n return new Promise((resolve) => {\n const handler = (changed: IValueChanged) => {\n if (changed.key === key) {\n map.off(\"valueChanged\", handler);\n const value = map.get<T>(changed.key);\n if (value === undefined) {\n throw new Error(\"Unexpected valueChanged result\");\n }\n resolve(value);\n }\n };\n map.on(\"valueChanged\", handler);\n });\n};\n\nconst schedulerId = \"scheduler\";\n\nexport class AgentScheduler extends TypedEventEmitter<IAgentSchedulerEvents> implements IAgentScheduler {\n public static async load(runtime: IFluidDataStoreRuntime, context: IFluidDataStoreContext, existing: boolean) {\n let root: ISharedMap;\n let consensusRegisterCollection: ConsensusRegisterCollection<string | null>;\n if (!existing) {\n root = SharedMap.create(runtime, \"root\");\n root.bindToContext();\n consensusRegisterCollection = ConsensusRegisterCollection.create(runtime);\n consensusRegisterCollection.bindToContext();\n root.set(schedulerId, consensusRegisterCollection.handle);\n } else {\n root = await runtime.getChannel(\"root\") as ISharedMap;\n const handle = await mapWait<IFluidHandle<ConsensusRegisterCollection<string | null>>>(root, schedulerId);\n assert(handle !== undefined, 0x116 /* \"Missing handle on scheduler load\" */);\n consensusRegisterCollection = await handle.get();\n }\n const agentScheduler = new AgentScheduler(runtime, context, consensusRegisterCollection);\n agentScheduler.initialize();\n\n return agentScheduler;\n }\n\n public get IAgentScheduler() { return this; }\n\n private get clientId(): string {\n if (this.runtime.attachState === AttachState.Detached) {\n return UnattachedClientId;\n }\n const clientId = this.runtime.clientId;\n assert(!!clientId, 0x117 /* \"Trying to get missing clientId!\" */);\n return clientId;\n }\n\n // Set of tasks registered by this client.\n // Has no relationship with lists below.\n // The only requirement here - a task can be registered by a client only once.\n // Other clients can pick these tasks.\n private readonly registeredTasks = new Set<string>();\n\n // List of all tasks client is capable of running (essentially expressed desire to run)\n // Client will proactively attempt to pick them up these tasks if they are not assigned to other clients.\n // This is a strict superset of tasks running in the client.\n private readonly locallyRunnableTasks = new Map<string, () => Promise<void>>();\n\n // Set of registered tasks client is currently running.\n // It's subset of this.locallyRunnableTasks\n private runningTasks = new Set<string>();\n\n private readonly _handle: IFluidHandle<this>;\n\n constructor(\n private readonly runtime: IFluidDataStoreRuntime,\n private readonly context: IFluidDataStoreContext,\n private readonly consensusRegisterCollection: ConsensusRegisterCollection<string | null>,\n ) {\n super();\n this._handle = new FluidObjectHandle(this, \"\", this.runtime.objectsRoutingContext);\n }\n\n public get handle() {\n return this._handle;\n }\n\n public async register(...taskUrls: string[]): Promise<void> {\n for (const taskUrl of taskUrls) {\n if (this.registeredTasks.has(taskUrl)) {\n throw new Error(`${taskUrl} is already registered`);\n }\n }\n const unregisteredTasks: string[] = [];\n for (const taskUrl of taskUrls) {\n this.registeredTasks.add(taskUrl);\n // Only register for a new task.\n const currentClient = this.getTaskClientId(taskUrl);\n if (currentClient === undefined) {\n unregisteredTasks.push(taskUrl);\n }\n }\n return this.registerCore(unregisteredTasks);\n }\n\n public async pick(taskId: string, worker: () => Promise<void>): Promise<void> {\n if (this.locallyRunnableTasks.has(taskId)) {\n throw new Error(`${taskId} is already attempted`);\n }\n this.locallyRunnableTasks.set(taskId, worker);\n\n // We have a policy to disallow non-interactive clients from taking tasks. Callers of pick() can\n // either perform this check proactively and call conditionally, or catch the error (in which case\n // they can know they will not get the task).\n assert(this.context.deltaManager.clientDetails.capabilities.interactive,\n 0x118 /* \"Bad client interactive check\" */);\n\n // Check the current status and express interest if it's a new one (undefined) or currently unpicked (null).\n if (this.isActive()) {\n const currentClient = this.getTaskClientId(taskId);\n if (currentClient === undefined || currentClient === null) {\n await this.writeCore(taskId, this.clientId);\n }\n }\n }\n\n public async release(...taskUrls: string[]): Promise<void> {\n const active = this.isActive();\n for (const taskUrl of taskUrls) {\n if (!this.locallyRunnableTasks.has(taskUrl)) {\n throw new Error(`${taskUrl} was never registered`);\n }\n // Note - the assumption is - we are connected.\n // If not - all tasks should have been dropped already on disconnect / attachment\n assert(active, 0x119 /* \"This agent became inactive while releasing\" */);\n if (this.getTaskClientId(taskUrl) !== this.clientId) {\n throw new Error(`${taskUrl} was never picked`);\n }\n }\n return this.releaseCore([...taskUrls]);\n }\n\n public pickedTasks(): string[] {\n return Array.from(this.runningTasks.values());\n }\n\n private async registerCore(taskUrls: string[]): Promise<void> {\n if (taskUrls.length > 0) {\n const registersP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n registersP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(registersP);\n\n // The registers should have up to date results now. Check the status.\n for (const taskUrl of taskUrls) {\n const taskStatus = this.getTaskClientId(taskUrl);\n\n // Task should be either registered (null) or picked up.\n assert(taskStatus !== undefined, 0x11a /* `Unsuccessful registration` */);\n }\n }\n }\n\n private async releaseCore(taskUrls: string[]) {\n if (taskUrls.length > 0) {\n const releasesP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n // Remove from local map so that it can be picked later.\n this.locallyRunnableTasks.delete(taskUrl);\n releasesP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(releasesP);\n }\n }\n\n private async clearTasks(taskUrls: string[]) {\n assert(this.isActive(), 0x11b /* \"Trying to clear tasks on inactive agent\" */);\n const clearP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n clearP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(clearP);\n }\n\n private getTaskClientId(url: string): string | null | undefined {\n return this.consensusRegisterCollection.read(url);\n }\n\n private async writeCore(key: string, clientId: string | null): Promise<void> {\n await this.consensusRegisterCollection.write(key, clientId);\n }\n\n private initialize() {\n const quorum = this.runtime.getQuorum();\n // A client left the quorum. Iterate and clear tasks held by that client.\n // Ideally a leader should do this cleanup. But it's complicated when a leader itself leaves.\n // Probably okay for now to have every client try to do this.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n quorum.on(\"removeMember\", async (clientId: string) => {\n assert(this.runtime.objectsRoutingContext.isAttached, 0x11c /* \"Detached object routing context\" */);\n // Cleanup only if connected. If not, cleanup will happen in initializeCore() that runs on connection.\n if (this.isActive()) {\n const tasks: Promise<any>[] = [];\n const leftTasks: string[] = [];\n for (const taskUrl of this.consensusRegisterCollection.keys()) {\n if (this.getTaskClientId(taskUrl) === clientId) {\n if (this.locallyRunnableTasks.has(taskUrl)) {\n tasks.push(this.writeCore(taskUrl, this.clientId));\n } else {\n leftTasks.push(taskUrl);\n }\n }\n }\n tasks.push(this.clearTasks(leftTasks));\n await Promise.all(tasks).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_RemoveMemberError\", error);\n });\n }\n });\n\n // Listeners for new/released tasks. All clients will try to grab at the same time.\n // May be we want a randomized timer (Something like raft) to reduce chattiness?\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.consensusRegisterCollection.on(\"atomicChanged\", async (key: string, currentClient: string | null) => {\n // Check if this client was chosen.\n if (this.isActive() && currentClient === this.clientId) {\n this.onNewTaskAssigned(key);\n } else {\n await this.onTaskReassigned(key, currentClient);\n }\n });\n\n if (this.isActive()) {\n this.initializeCore();\n }\n\n this.runtime.on(\"connected\", () => {\n if (this.isActive()) {\n this.initializeCore();\n }\n });\n\n if (this.runtime.attachState === AttachState.Detached) {\n this.runtime.waitAttached().then(() => {\n this.clearRunningTasks();\n }).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_clearRunningTasks\", error);\n });\n }\n\n this.runtime.on(\"disconnected\", () => {\n if (this.runtime.attachState !== AttachState.Detached) {\n this.clearRunningTasks();\n }\n });\n }\n\n private onNewTaskAssigned(key: string) {\n assert(!this.runningTasks.has(key), 0x11d /* \"task is already running\" */);\n this.runningTasks.add(key);\n const worker = this.locallyRunnableTasks.get(key);\n if (worker === undefined) {\n this.sendErrorEvent(\"AgentScheduler_UnwantedChange\", undefined, key);\n }\n else {\n this.emit(\"picked\", key);\n worker().catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_FailedWork\", error, key);\n });\n }\n }\n\n private async onTaskReassigned(key: string, currentClient: string | null) {\n if (this.runningTasks.has(key)) {\n this.runningTasks.delete(key);\n this.emit(\"released\", key);\n }\n assert(currentClient !== undefined, 0x11e /* \"client is undefined\" */);\n if (this.isActive()) {\n // attempt to pick up task if we are connected.\n // If not, initializeCore() will do it when connected\n if (currentClient === null) {\n if (this.locallyRunnableTasks.has(key)) {\n await this.writeCore(key, this.clientId);\n }\n }\n // Check if the op came from dropped client\n // This could happen when \"old\" ops are submitted on reconnection.\n // They carry \"old\" ref seq number, but if write is not contested, it will get accepted\n else if (this.runtime.getQuorum().getMember(currentClient) === undefined) {\n await this.writeCore(key, null);\n }\n }\n }\n\n private isActive() {\n // Scheduler should be active in detached container.\n if (this.runtime.attachState === AttachState.Detached) {\n return true;\n }\n if (!this.runtime.connected) {\n return false;\n }\n\n // Note: we are not checking for this.context.deltaManager.clientDetails.capabilities.interactive\n // here. Instead we assert in pick() if a non-interactive client tries to pick.\n\n return this.context.deltaManager.active;\n }\n\n private initializeCore() {\n // Nobody released the tasks held by last client in previous session.\n // Check to see if this client needs to do this.\n const clearCandidates: string[] = [];\n const tasks: Promise<any>[] = [];\n\n for (const [taskUrl] of this.locallyRunnableTasks) {\n if (!this.getTaskClientId(taskUrl)) {\n tasks.push(this.writeCore(taskUrl, this.clientId));\n }\n }\n\n for (const taskUrl of this.consensusRegisterCollection.keys()) {\n const currentClient = this.getTaskClientId(taskUrl);\n if (currentClient && this.runtime.getQuorum().getMember(currentClient) === undefined) {\n clearCandidates.push(taskUrl);\n }\n }\n\n tasks.push(this.clearTasks(clearCandidates));\n\n Promise.all(tasks).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_InitError\", error);\n });\n }\n\n private clearRunningTasks() {\n const tasks = this.runningTasks;\n this.runningTasks = new Set<string>();\n\n if (this.isActive()) {\n // Clear all tasks with UnattachedClientId (if was unattached) and reapply for tasks with new clientId\n // If we are simply disconnected, then proper cleanup will be done on connection.\n this.initializeCore();\n }\n\n for (const task of tasks) {\n this.emit(\"lost\", task);\n }\n }\n\n private sendErrorEvent(eventName: string, error: any, key?: string) {\n this.runtime.logger.sendErrorEvent({ eventName, key }, error);\n }\n}\n\nclass AgentSchedulerRuntime extends FluidDataStoreRuntime {\n private readonly agentSchedulerP: Promise<AgentScheduler>;\n constructor(\n dataStoreContext: IFluidDataStoreContext,\n sharedObjectRegistry: ISharedObjectRegistry,\n existing: boolean,\n ) {\n super(dataStoreContext, sharedObjectRegistry, existing);\n this.agentSchedulerP = AgentScheduler.load(this, dataStoreContext, existing);\n }\n public async request(request: IRequest) {\n const response = await super.request(request);\n if (response.status === 404) {\n if (request.url === \"\" || request.url === \"/\") {\n const agentScheduler = await this.agentSchedulerP;\n return { status: 200, mimeType: \"fluid/object\", value: agentScheduler };\n }\n }\n return response;\n }\n}\n\nexport class AgentSchedulerFactory implements IFluidDataStoreFactory {\n public static readonly type = \"_scheduler\";\n public readonly type = AgentSchedulerFactory.type;\n\n public get IFluidDataStoreFactory() { return this; }\n\n public static get registryEntry(): NamedFluidDataStoreRegistryEntry {\n return [this.type, Promise.resolve(new AgentSchedulerFactory())];\n }\n\n public static async createChildInstance(parentContext: IFluidDataStoreContext): Promise<AgentScheduler> {\n const packagePath = [...parentContext.packagePath, AgentSchedulerFactory.type];\n const router = await parentContext.containerRuntime.createDataStore(packagePath);\n return requestFluidObject<AgentScheduler>(router, \"/\");\n }\n\n public async instantiateDataStore(context: IFluidDataStoreContext, existing: boolean) {\n const mapFactory = SharedMap.getFactory();\n const consensusRegisterCollectionFactory = ConsensusRegisterCollection.getFactory();\n const dataTypes = new Map<string, IChannelFactory>();\n dataTypes.set(mapFactory.type, mapFactory);\n dataTypes.set(consensusRegisterCollectionFactory.type, consensusRegisterCollectionFactory);\n\n return new AgentSchedulerRuntime(context, dataTypes, existing);\n }\n}\n"]}
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n IFluidHandle,\n IRequest,\n} from \"@fluidframework/core-interfaces\";\nimport {\n FluidDataStoreRuntime,\n FluidObjectHandle,\n ISharedObjectRegistry,\n} from \"@fluidframework/datastore\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ISharedMap, IValueChanged, SharedMap } from \"@fluidframework/map\";\nimport { ConsensusRegisterCollection } from \"@fluidframework/register-collection\";\nimport { IFluidDataStoreRuntime, IChannelFactory } from \"@fluidframework/datastore-definitions\";\nimport {\n IFluidDataStoreContext,\n IFluidDataStoreFactory,\n NamedFluidDataStoreRegistryEntry,\n} from \"@fluidframework/runtime-definitions\";\nimport { requestFluidObject } from \"@fluidframework/runtime-utils\";\nimport { v4 as uuid } from \"uuid\";\nimport { IAgentScheduler, IAgentSchedulerEvents } from \"./agent\";\n\n// Note: making sure this ID is unique and does not collide with storage provided clientID\nconst UnattachedClientId = `${uuid()}_unattached`;\n\nconst mapWait = async <T = any>(map: ISharedMap, key: string): Promise<T> => {\n const maybeValue = map.get<T>(key);\n if (maybeValue !== undefined) {\n return maybeValue;\n }\n\n return new Promise((resolve) => {\n const handler = (changed: IValueChanged) => {\n if (changed.key === key) {\n map.off(\"valueChanged\", handler);\n const value = map.get<T>(changed.key);\n if (value === undefined) {\n throw new Error(\"Unexpected valueChanged result\");\n }\n resolve(value);\n }\n };\n map.on(\"valueChanged\", handler);\n });\n};\n\nconst schedulerId = \"scheduler\";\n\nexport class AgentScheduler extends TypedEventEmitter<IAgentSchedulerEvents> implements IAgentScheduler {\n public static async load(runtime: IFluidDataStoreRuntime, context: IFluidDataStoreContext, existing: boolean) {\n let root: ISharedMap;\n let consensusRegisterCollection: ConsensusRegisterCollection<string | null>;\n if (!existing) {\n root = SharedMap.create(runtime, \"root\");\n root.bindToContext();\n consensusRegisterCollection = ConsensusRegisterCollection.create(runtime);\n consensusRegisterCollection.bindToContext();\n root.set(schedulerId, consensusRegisterCollection.handle);\n } else {\n root = await runtime.getChannel(\"root\") as ISharedMap;\n const handle = await mapWait<IFluidHandle<ConsensusRegisterCollection<string | null>>>(root, schedulerId);\n assert(handle !== undefined, 0x116 /* \"Missing handle on scheduler load\" */);\n consensusRegisterCollection = await handle.get();\n }\n const agentScheduler = new AgentScheduler(runtime, context, consensusRegisterCollection);\n agentScheduler.initialize();\n\n return agentScheduler;\n }\n\n public get IAgentScheduler() { return this; }\n\n private get clientId(): string {\n if (this.runtime.attachState === AttachState.Detached) {\n return UnattachedClientId;\n }\n const clientId = this.runtime.clientId;\n assert(!!clientId, 0x117 /* \"Trying to get missing clientId!\" */);\n return clientId;\n }\n\n // Set of tasks registered by this client.\n // Has no relationship with lists below.\n // The only requirement here - a task can be registered by a client only once.\n // Other clients can pick these tasks.\n private readonly registeredTasks = new Set<string>();\n\n // List of all tasks client is capable of running (essentially expressed desire to run)\n // Client will proactively attempt to pick them up these tasks if they are not assigned to other clients.\n // This is a strict superset of tasks running in the client.\n private readonly locallyRunnableTasks = new Map<string, () => Promise<void>>();\n\n // Set of registered tasks client is currently running.\n // It's subset of this.locallyRunnableTasks\n private runningTasks = new Set<string>();\n\n private readonly _handle: IFluidHandle<this>;\n\n constructor(\n private readonly runtime: IFluidDataStoreRuntime,\n private readonly context: IFluidDataStoreContext,\n private readonly consensusRegisterCollection: ConsensusRegisterCollection<string | null>,\n ) {\n super();\n this._handle = new FluidObjectHandle(this, \"\", this.runtime.objectsRoutingContext);\n }\n\n public get handle() {\n return this._handle;\n }\n\n public async register(...taskUrls: string[]): Promise<void> {\n for (const taskUrl of taskUrls) {\n if (this.registeredTasks.has(taskUrl)) {\n throw new Error(`${taskUrl} is already registered`);\n }\n }\n const unregisteredTasks: string[] = [];\n for (const taskUrl of taskUrls) {\n this.registeredTasks.add(taskUrl);\n // Only register for a new task.\n const currentClient = this.getTaskClientId(taskUrl);\n if (currentClient === undefined) {\n unregisteredTasks.push(taskUrl);\n }\n }\n return this.registerCore(unregisteredTasks);\n }\n\n public async pick(taskId: string, worker: () => Promise<void>): Promise<void> {\n if (this.locallyRunnableTasks.has(taskId)) {\n throw new Error(`${taskId} is already attempted`);\n }\n this.locallyRunnableTasks.set(taskId, worker);\n\n // We have a policy to disallow non-interactive clients from taking tasks. Callers of pick() can\n // either perform this check proactively and call conditionally, or catch the error (in which case\n // they can know they will not get the task).\n assert(this.context.deltaManager.clientDetails.capabilities.interactive,\n 0x118 /* \"Bad client interactive check\" */);\n\n // Check the current status and express interest if it's a new one (undefined) or currently unpicked (null).\n if (this.isActive()) {\n const currentClient = this.getTaskClientId(taskId);\n if (currentClient === undefined || currentClient === null) {\n await this.writeCore(taskId, this.clientId);\n }\n }\n }\n\n public async release(...taskUrls: string[]): Promise<void> {\n const active = this.isActive();\n for (const taskUrl of taskUrls) {\n if (!this.locallyRunnableTasks.has(taskUrl)) {\n throw new Error(`${taskUrl} was never registered`);\n }\n // Note - the assumption is - we are connected.\n // If not - all tasks should have been dropped already on disconnect / attachment\n assert(active, 0x119 /* \"This agent became inactive while releasing\" */);\n if (this.getTaskClientId(taskUrl) !== this.clientId) {\n throw new Error(`${taskUrl} was never picked`);\n }\n }\n return this.releaseCore([...taskUrls]);\n }\n\n public pickedTasks(): string[] {\n return Array.from(this.runningTasks.values());\n }\n\n private async registerCore(taskUrls: string[]): Promise<void> {\n if (taskUrls.length > 0) {\n const registersP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n registersP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(registersP);\n\n // The registers should have up to date results now. Check the status.\n for (const taskUrl of taskUrls) {\n const taskStatus = this.getTaskClientId(taskUrl);\n\n // Task should be either registered (null) or picked up.\n assert(taskStatus !== undefined, 0x11a /* `Unsuccessful registration` */);\n }\n }\n }\n\n private async releaseCore(taskUrls: string[]) {\n if (taskUrls.length > 0) {\n const releasesP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n // Remove from local map so that it can be picked later.\n this.locallyRunnableTasks.delete(taskUrl);\n releasesP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(releasesP);\n }\n }\n\n private async clearTasks(taskUrls: string[]) {\n assert(this.isActive(), 0x11b /* \"Trying to clear tasks on inactive agent\" */);\n const clearP: Promise<void>[] = [];\n for (const taskUrl of taskUrls) {\n clearP.push(this.writeCore(taskUrl, null));\n }\n await Promise.all(clearP);\n }\n\n private getTaskClientId(url: string): string | null | undefined {\n return this.consensusRegisterCollection.read(url);\n }\n\n private async writeCore(key: string, clientId: string | null): Promise<void> {\n await this.consensusRegisterCollection.write(key, clientId);\n }\n\n private initialize() {\n const quorum = this.runtime.getQuorum();\n // A client left the quorum. Iterate and clear tasks held by that client.\n // Ideally a leader should do this cleanup. But it's complicated when a leader itself leaves.\n // Probably okay for now to have every client try to do this.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n quorum.on(\"removeMember\", async (clientId: string) => {\n assert(this.runtime.objectsRoutingContext.isAttached, 0x11c /* \"Detached object routing context\" */);\n // Cleanup only if connected. If not, cleanup will happen in initializeCore() that runs on connection.\n if (this.isActive()) {\n const tasks: Promise<any>[] = [];\n const leftTasks: string[] = [];\n for (const taskUrl of this.consensusRegisterCollection.keys()) {\n if (this.getTaskClientId(taskUrl) === clientId) {\n if (this.locallyRunnableTasks.has(taskUrl)) {\n tasks.push(this.writeCore(taskUrl, this.clientId));\n } else {\n leftTasks.push(taskUrl);\n }\n }\n }\n tasks.push(this.clearTasks(leftTasks));\n await Promise.all(tasks).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_RemoveMemberError\", error);\n });\n }\n });\n\n // Listeners for new/released tasks. All clients will try to grab at the same time.\n // May be we want a randomized timer (Something like raft) to reduce chattiness?\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n this.consensusRegisterCollection.on(\"atomicChanged\", async (key: string, currentClient: string | null) => {\n // Check if this client was chosen.\n if (this.isActive() && currentClient === this.clientId) {\n this.onNewTaskAssigned(key);\n } else {\n await this.onTaskReassigned(key, currentClient);\n }\n });\n\n if (this.isActive()) {\n this.initializeCore();\n }\n\n this.runtime.on(\"connected\", () => {\n if (this.isActive()) {\n this.initializeCore();\n }\n });\n\n if (this.runtime.attachState === AttachState.Detached) {\n this.runtime.waitAttached().then(() => {\n this.clearRunningTasks();\n }).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_clearRunningTasks\", error);\n });\n }\n\n this.runtime.on(\"disconnected\", () => {\n if (this.runtime.attachState !== AttachState.Detached) {\n this.clearRunningTasks();\n }\n });\n }\n\n private onNewTaskAssigned(key: string) {\n assert(!this.runningTasks.has(key), 0x11d /* \"task is already running\" */);\n this.runningTasks.add(key);\n const worker = this.locallyRunnableTasks.get(key);\n if (worker === undefined) {\n this.sendErrorEvent(\"AgentScheduler_UnwantedChange\", undefined, key);\n } else {\n this.emit(\"picked\", key);\n worker().catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_FailedWork\", error, key);\n });\n }\n }\n\n private async onTaskReassigned(key: string, currentClient: string | null) {\n if (this.runningTasks.has(key)) {\n this.runningTasks.delete(key);\n this.emit(\"released\", key);\n }\n assert(currentClient !== undefined, 0x11e /* \"client is undefined\" */);\n /* eslint-disable @typescript-eslint/brace-style */\n if (this.isActive()) {\n // attempt to pick up task if we are connected.\n // If not, initializeCore() will do it when connected\n if (currentClient === null) {\n if (this.locallyRunnableTasks.has(key)) {\n await this.writeCore(key, this.clientId);\n }\n }\n // Check if the op came from dropped client\n // This could happen when \"old\" ops are submitted on reconnection.\n // They carry \"old\" ref seq number, but if write is not contested, it will get accepted\n else if (this.runtime.getQuorum().getMember(currentClient) === undefined) {\n await this.writeCore(key, null);\n }\n }\n /* eslint-enable @typescript-eslint/brace-style */\n }\n\n private isActive() {\n // Scheduler should be active in detached container.\n if (this.runtime.attachState === AttachState.Detached) {\n return true;\n }\n if (!this.runtime.connected) {\n return false;\n }\n\n // Note: we are not checking for this.context.deltaManager.clientDetails.capabilities.interactive\n // here. Instead we assert in pick() if a non-interactive client tries to pick.\n\n return this.context.deltaManager.active;\n }\n\n private initializeCore() {\n // Nobody released the tasks held by last client in previous session.\n // Check to see if this client needs to do this.\n const clearCandidates: string[] = [];\n const tasks: Promise<any>[] = [];\n\n for (const [taskUrl] of this.locallyRunnableTasks) {\n if (!this.getTaskClientId(taskUrl)) {\n tasks.push(this.writeCore(taskUrl, this.clientId));\n }\n }\n\n for (const taskUrl of this.consensusRegisterCollection.keys()) {\n const currentClient = this.getTaskClientId(taskUrl);\n if (currentClient && this.runtime.getQuorum().getMember(currentClient) === undefined) {\n clearCandidates.push(taskUrl);\n }\n }\n\n tasks.push(this.clearTasks(clearCandidates));\n\n Promise.all(tasks).catch((error) => {\n this.sendErrorEvent(\"AgentScheduler_InitError\", error);\n });\n }\n\n private clearRunningTasks() {\n const tasks = this.runningTasks;\n this.runningTasks = new Set<string>();\n\n if (this.isActive()) {\n // Clear all tasks with UnattachedClientId (if was unattached) and reapply for tasks with new clientId\n // If we are simply disconnected, then proper cleanup will be done on connection.\n this.initializeCore();\n }\n\n for (const task of tasks) {\n this.emit(\"lost\", task);\n }\n }\n\n private sendErrorEvent(eventName: string, error: any, key?: string) {\n this.runtime.logger.sendErrorEvent({ eventName, key }, error);\n }\n}\n\nclass AgentSchedulerRuntime extends FluidDataStoreRuntime {\n private readonly agentSchedulerP: Promise<AgentScheduler>;\n constructor(\n dataStoreContext: IFluidDataStoreContext,\n sharedObjectRegistry: ISharedObjectRegistry,\n existing: boolean,\n ) {\n super(dataStoreContext, sharedObjectRegistry, existing);\n this.agentSchedulerP = AgentScheduler.load(this, dataStoreContext, existing);\n }\n public async request(request: IRequest) {\n const response = await super.request(request);\n if (response.status === 404) {\n if (request.url === \"\" || request.url === \"/\") {\n const agentScheduler = await this.agentSchedulerP;\n return { status: 200, mimeType: \"fluid/object\", value: agentScheduler };\n }\n }\n return response;\n }\n}\n\nexport class AgentSchedulerFactory implements IFluidDataStoreFactory {\n public static readonly type = \"_scheduler\";\n public readonly type = AgentSchedulerFactory.type;\n\n public get IFluidDataStoreFactory() { return this; }\n\n public static get registryEntry(): NamedFluidDataStoreRegistryEntry {\n return [this.type, Promise.resolve(new AgentSchedulerFactory())];\n }\n\n public static async createChildInstance(parentContext: IFluidDataStoreContext): Promise<AgentScheduler> {\n const packagePath = [...parentContext.packagePath, AgentSchedulerFactory.type];\n const router = await parentContext.containerRuntime.createDataStore(packagePath);\n return requestFluidObject<AgentScheduler>(router, \"/\");\n }\n\n public async instantiateDataStore(context: IFluidDataStoreContext, existing: boolean) {\n const mapFactory = SharedMap.getFactory();\n const consensusRegisterCollectionFactory = ConsensusRegisterCollection.getFactory();\n const dataTypes = new Map<string, IChannelFactory>();\n dataTypes.set(mapFactory.type, mapFactory);\n dataTypes.set(consensusRegisterCollectionFactory.type, consensusRegisterCollectionFactory);\n\n return new AgentSchedulerRuntime(context, dataTypes, existing);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/agent-scheduler",
3
- "version": "0.59.2000",
3
+ "version": "0.59.3000-67119",
4
4
  "description": "Built in runtime object for distributing agents across instances of a container",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -55,18 +55,18 @@
55
55
  "@fluidframework/common-utils": "^0.32.1",
56
56
  "@fluidframework/container-definitions": "^0.48.1000",
57
57
  "@fluidframework/core-interfaces": "^0.43.1000",
58
- "@fluidframework/datastore": "^0.59.2000",
59
- "@fluidframework/datastore-definitions": "^0.59.2000",
60
- "@fluidframework/map": "^0.59.2000",
61
- "@fluidframework/register-collection": "^0.59.2000",
62
- "@fluidframework/runtime-definitions": "^0.59.2000",
63
- "@fluidframework/runtime-utils": "^0.59.2000",
58
+ "@fluidframework/datastore": "0.59.3000-67119",
59
+ "@fluidframework/datastore-definitions": "0.59.3000-67119",
60
+ "@fluidframework/map": "0.59.3000-67119",
61
+ "@fluidframework/register-collection": "0.59.3000-67119",
62
+ "@fluidframework/runtime-definitions": "0.59.3000-67119",
63
+ "@fluidframework/runtime-utils": "0.59.3000-67119",
64
64
  "uuid": "^8.3.1"
65
65
  },
66
66
  "devDependencies": {
67
- "@fluidframework/agent-scheduler-previous": "npm:@fluidframework/agent-scheduler@0.59.1000",
67
+ "@fluidframework/agent-scheduler-previous": "npm:@fluidframework/agent-scheduler@0.59.2000",
68
68
  "@fluidframework/build-common": "^0.23.0",
69
- "@fluidframework/eslint-config-fluid": "^0.28.1000",
69
+ "@fluidframework/eslint-config-fluid": "^0.28.2000-0",
70
70
  "@rushstack/eslint-config": "^2.5.1",
71
71
  "@types/mocha": "^8.2.2",
72
72
  "@types/node": "^14.18.0",
@@ -86,7 +86,7 @@
86
86
  "mocha": "^8.4.0",
87
87
  "nyc": "^15.0.0",
88
88
  "rimraf": "^2.6.2",
89
- "typescript": "~4.1.3",
89
+ "typescript": "~4.5.5",
90
90
  "typescript-formatter": "7.1.0"
91
91
  },
92
92
  "fluid": {
@@ -100,7 +100,7 @@
100
100
  }
101
101
  },
102
102
  "typeValidation": {
103
- "version": "0.59.2000",
103
+ "version": "0.59.3000",
104
104
  "broken": {}
105
105
  }
106
106
  }
package/src/agent.ts CHANGED
@@ -25,7 +25,7 @@ export interface IAgentSchedulerEvents extends IEvent {
25
25
  * unless release() is called)
26
26
  * @param listener - callback notified when change happened for particular key
27
27
  */
28
- (event: "picked" | "released" | "lost", listener: (taskId: string) => void)
28
+ (event: "picked" | "released" | "lost", listener: (taskId: string) => void);
29
29
  }
30
30
 
31
31
  /**
package/src/scheduler.ts CHANGED
@@ -292,8 +292,7 @@ export class AgentScheduler extends TypedEventEmitter<IAgentSchedulerEvents> imp
292
292
  const worker = this.locallyRunnableTasks.get(key);
293
293
  if (worker === undefined) {
294
294
  this.sendErrorEvent("AgentScheduler_UnwantedChange", undefined, key);
295
- }
296
- else {
295
+ } else {
297
296
  this.emit("picked", key);
298
297
  worker().catch((error) => {
299
298
  this.sendErrorEvent("AgentScheduler_FailedWork", error, key);
@@ -307,6 +306,7 @@ export class AgentScheduler extends TypedEventEmitter<IAgentSchedulerEvents> imp
307
306
  this.emit("released", key);
308
307
  }
309
308
  assert(currentClient !== undefined, 0x11e /* "client is undefined" */);
309
+ /* eslint-disable @typescript-eslint/brace-style */
310
310
  if (this.isActive()) {
311
311
  // attempt to pick up task if we are connected.
312
312
  // If not, initializeCore() will do it when connected
@@ -322,6 +322,7 @@ export class AgentScheduler extends TypedEventEmitter<IAgentSchedulerEvents> imp
322
322
  await this.writeCore(key, null);
323
323
  }
324
324
  }
325
+ /* eslint-enable @typescript-eslint/brace-style */
325
326
  }
326
327
 
327
328
  private isActive() {