Skip to content

Commit

Permalink
Fixed memory leak in internal actor registry
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Jan 22, 2020
1 parent 0ba791f commit f86d419
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .changeset/nice-cobras-suffer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'xstate': patch
---

Fixed memory leak - each created service has been registered in internal map but it was never removed from it. Registration has been moved to a point where Interpreter is being started and it's deregistered when it is being stopped.
8 changes: 4 additions & 4 deletions packages/core/src/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,7 @@ export class Interpreter<
*/
constructor(
public machine: StateMachine<TContext, TStateSchema, TEvent, TTypestate>,
options: Partial<InterpreterOptions> = Interpreter.defaultOptions,
sessionId?: string
options: Partial<InterpreterOptions> = Interpreter.defaultOptions
) {
const resolvedOptions: InterpreterOptions = {
...Interpreter.defaultOptions,
Expand All @@ -214,8 +213,7 @@ export class Interpreter<
deferEvents: this.options.deferEvents
});

this.sessionId =
sessionId !== undefined ? sessionId : registry.register(this as Actor);
this.sessionId = registry.bookId();
}
public get initialState(): State<TContext, TEvent> {
if (this._initialState) {
Expand Down Expand Up @@ -462,6 +460,7 @@ export class Interpreter<
return this;
}

registry.register(this.sessionId, this as Actor);
this.initialized = true;
this._status = InterpreterStatus.Running;

Expand Down Expand Up @@ -520,6 +519,7 @@ export class Interpreter<
this.scheduler.clear();
this.initialized = false;
this._status = InterpreterStatus.Stopped;
registry.free(this.sessionId);

return this;
}
Expand Down
18 changes: 9 additions & 9 deletions packages/core/src/registry.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { Actor } from './Actor';

const children = new Map<string, Actor>();
const idMap = new Map<Actor, string>();

let sessionIdIndex = 0;

export interface Registry {
register(actor: Actor): string;
bookId(): string;
register(id: string, actor: Actor): string;
get(id: string): Actor | undefined;
lookup(actor: Actor): string | undefined;
free(id: string): void;
}

export const registry: Registry = {
register(actor) {
const id = `x:${sessionIdIndex++}`;
bookId() {
return `x:${sessionIdIndex++}`;
},
register(id, actor) {
children.set(id, actor);
idMap.set(actor, id);

return id;
},
get(id) {
return children.get(id);
},
lookup(actorRef) {
return idMap.get(actorRef);
free(id) {
children.delete(id);
}
};

0 comments on commit f86d419

Please sign in to comment.