Skip to content

Commit 358908e

Browse files
committed
feat(WebWorker): Expose MessageBroker API
Closes angular#3942
1 parent 6532171 commit 358908e

File tree

31 files changed

+267
-275
lines changed

31 files changed

+267
-275
lines changed

modules/angular2/src/web_workers/shared/client_message_broker.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {ListWrapper, StringMapWrapper, MapWrapper} from "angular2/src/core/facad
1212
import {Serializer} from "angular2/src/web_workers/shared/serializer";
1313
import {Injectable} from "angular2/di";
1414
import {Type, StringWrapper} from "angular2/src/core/facade/lang";
15+
export {Type} from "angular2/src/core/facade/lang";
1516

1617
@Injectable()
1718
export class ClientMessageBrokerFactory {
@@ -29,7 +30,8 @@ export class ClientMessageBroker {
2930
constructor(messageBus: MessageBus, protected _serializer: Serializer, public channel) {
3031
this._sink = messageBus.to(channel);
3132
var source = messageBus.from(channel);
32-
ObservableWrapper.subscribe(source, (message) => this._handleMessage(message));
33+
ObservableWrapper.subscribe(source,
34+
(message: StringMap<string, any>) => this._handleMessage(message));
3335
}
3436

3537
private _generateMessageId(name: string): string {
@@ -43,7 +45,7 @@ export class ClientMessageBroker {
4345
return id;
4446
}
4547

46-
runOnUiThread(args: UiArguments, returnType: Type): Promise<any> {
48+
runOnService(args: UiArguments, returnType: Type): Promise<any> {
4749
var fnArgs = [];
4850
if (isPresent(args.args)) {
4951
ListWrapper.forEach(args.args, (argument) => {
@@ -128,7 +130,7 @@ class MessageData {
128130
}
129131

130132
export class FnArg {
131-
constructor(public value, public type) {}
133+
constructor(public value, public type: Type) {}
132134
}
133135

134136
export class UiArguments {

modules/angular2/src/web_workers/ui/application.dart

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import 'dart:async';
55
import 'dart:core';
66
import 'package:angular2/src/web_workers/shared/message_bus.dart'
77
show MessageBus;
8-
import 'package:angular2/src/web_workers/ui/impl.dart' show bootstrapUICommon;
8+
import 'package:angular2/src/web_workers/ui/impl.dart' show bootstrapUICommon, WebWorkerApplication;
99
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
1010

1111
/**
@@ -14,26 +14,24 @@ import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
1414
* You instantiate a WebWorker application by calling bootstrap with the URI of your worker's index script
1515
* Note: The WebWorker script must call bootstrapWebworker once it is set up to complete the bootstrapping process
1616
*/
17-
Future<MessageBus> bootstrap(String uri) {
18-
return spawnWebWorker(Uri.parse(uri)).then((bus) {
19-
bootstrapUICommon(bus);
20-
return bus;
21-
});
17+
Future<IsolateInstance> bootstrap(String uri) async {
18+
var instance = await spawnWebWorker(Uri.parse(uri));
19+
instance.app = bootstrapUICommon(instance.bus);
20+
return instance;
2221
}
2322

2423
/**
2524
* To be called from the main thread to spawn and communicate with the worker thread
2625
*/
27-
Future<MessageBus> spawnWebWorker(Uri uri) {
26+
Future<IsolateInstance> spawnWebWorker(Uri uri) async {
2827
var receivePort = new ReceivePort();
2928
var isolateEndSendPort = receivePort.sendPort;
30-
return Isolate.spawnUri(uri, const [], isolateEndSendPort).then((_) {
31-
var source = new UIMessageBusSource(receivePort);
32-
return source.sink.then((sendPort) {
33-
var sink = new IsolateMessageBusSink(sendPort);
34-
return new IsolateMessageBus(sink, source);
35-
});
36-
});
29+
var isolate = await Isolate.spawnUri(uri, const [], isolateEndSendPort);
30+
var source = new UIMessageBusSource(receivePort);
31+
var sendPort = await source.sink;
32+
var sink = new IsolateMessageBusSink(sendPort);
33+
var bus = new IsolateMessageBus(sink, source);
34+
return new IsolateInstance(null, isolate, bus);
3735
}
3836

3937
class UIMessageBusSource extends IsolateMessageBusSource {
@@ -43,3 +41,15 @@ class UIMessageBusSource extends IsolateMessageBusSource {
4341
return message is SendPort;
4442
});
4543
}
44+
45+
/**
46+
* Wrapper class that exposes the {@link WebWorkerApplication}
47+
* Isolate instance and underyling {@link MessageBus} for lower level message passing.
48+
*/
49+
class IsolateInstance {
50+
WebWorkerApplication app;
51+
final Isolate isolate;
52+
final MessageBus bus;
53+
54+
IsolateInstance(this.app, this.isolate, this.bus);
55+
}

modules/angular2/src/web_workers/ui/application.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ import {
44
PostMessageBusSource
55
} from 'angular2/src/web_workers/shared/post_message_bus';
66
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
7-
import {BaseException} from "angular2/src/core/facade/lang";
8-
import {bootstrapUICommon} from "angular2/src/web_workers/ui/impl";
7+
import {BaseException} from 'angular2/src/core/facade/lang';
8+
import {bootstrapUICommon, WebWorkerApplication} from 'angular2/src/web_workers/ui/impl';
9+
export {WebWorkerApplication} from 'angular2/src/web_workers/ui/impl';
910
export * from 'angular2/src/web_workers/shared/message_bus';
1011

1112
/**
@@ -16,15 +17,24 @@ export * from 'angular2/src/web_workers/shared/message_bus';
1617
* Note: The WebWorker script must call bootstrapWebworker once it is set up to complete the
1718
* bootstrapping process
1819
*/
19-
export function bootstrap(uri: string): MessageBus {
20-
var messageBus = spawnWebWorker(uri);
21-
bootstrapUICommon(messageBus);
22-
return messageBus;
20+
export function bootstrap(uri: string): WebWorkerInstance {
21+
var instance = spawnWebWorker(uri);
22+
instance.app = bootstrapUICommon(instance.bus);
23+
return instance;
2324
}
2425

25-
export function spawnWebWorker(uri: string): MessageBus {
26+
export function spawnWebWorker(uri: string): WebWorkerInstance {
2627
var webWorker: Worker = new Worker(uri);
2728
var sink = new PostMessageBusSink(webWorker);
2829
var source = new PostMessageBusSource(webWorker);
29-
return new PostMessageBus(sink, source);
30+
var bus = new PostMessageBus(sink, source);
31+
return new WebWorkerInstance(null, webWorker, bus);
32+
}
33+
34+
/**
35+
* Wrapper class that exposes the {@link WebWorkerApplication}
36+
* Isolate instance and underyling {@link MessageBus} for lower level message passing.
37+
*/
38+
export class WebWorkerInstance {
39+
constructor(public app: WebWorkerApplication, public worker: Worker, public bus: MessageBus) {}
3040
}

modules/angular2/src/web_workers/ui/di_bindings.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// There should be a way to refactor application so that this file is unnecessary. See #3277
33
import {Injector, bind, Binding} from "angular2/di";
44
import {Reflector, reflector} from 'angular2/src/core/reflection/reflection';
5-
import {ListWrapper} from 'angular2/src/core/facade/collection';
65
import {
76
Parser,
87
Lexer,
@@ -61,13 +60,14 @@ import {
6160
RenderViewWithFragmentsStore
6261
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
6362
import {AnchorBasedAppRootUrl} from 'angular2/src/core/services/anchor_based_app_root_url';
64-
import {WebWorkerMain} from 'angular2/src/web_workers/ui/impl';
63+
import {WebWorkerApplication} from 'angular2/src/web_workers/ui/impl';
6564
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
6665
import {MessageBasedRenderCompiler} from 'angular2/src/web_workers/ui/render_compiler';
6766
import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer';
6867
import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl';
6968
import {WebWorkerSetup} from 'angular2/src/web_workers/ui/setup';
7069
import {ServiceMessageBrokerFactory} from 'angular2/src/web_workers/shared/service_message_broker';
70+
import {ClientMessageBrokerFactory} from 'angular2/src/web_workers/shared/client_message_broker';
7171

7272
var _rootInjector: Injector;
7373

@@ -134,12 +134,13 @@ function _injectorBindings(): any[] {
134134
Testability,
135135
AnchorBasedAppRootUrl,
136136
bind(AppRootUrl).toAlias(AnchorBasedAppRootUrl),
137-
WebWorkerMain,
137+
WebWorkerApplication,
138138
WebWorkerSetup,
139139
MessageBasedRenderCompiler,
140140
MessageBasedXHRImpl,
141141
MessageBasedRenderer,
142-
ServiceMessageBrokerFactory
142+
ServiceMessageBrokerFactory,
143+
ClientMessageBrokerFactory
143144
];
144145
}
145146

modules/angular2/src/web_workers/ui/impl.ts

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,43 @@ import {WebWorkerSetup} from 'angular2/src/web_workers/ui/setup';
1515
import {MessageBasedRenderCompiler} from 'angular2/src/web_workers/ui/render_compiler';
1616
import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer';
1717
import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl';
18+
import {
19+
ClientMessageBrokerFactory,
20+
ClientMessageBroker,
21+
} from 'angular2/src/web_workers/shared/client_message_broker';
22+
import {
23+
ServiceMessageBrokerFactory,
24+
ServiceMessageBroker
25+
} from 'angular2/src/web_workers/shared/service_message_broker';
1826

1927
/**
2028
* Creates a zone, sets up the DI bindings
2129
* And then creates a new WebWorkerMain object to handle messages from the worker
2230
*/
23-
export function bootstrapUICommon(bus: MessageBus) {
31+
export function bootstrapUICommon(bus: MessageBus): WebWorkerApplication {
2432
BrowserDomAdapter.makeCurrent();
2533
var zone = createNgZone();
2634
wtfInit();
27-
zone.run(() => {
35+
return zone.run(() => {
2836
var injector = createInjector(zone, bus);
29-
// necessary to kick off all the message based components
30-
injector.get(WebWorkerMain);
37+
injector.get(MessageBasedRenderCompiler).start();
38+
injector.get(MessageBasedRenderer).start();
39+
injector.get(MessageBasedXHRImpl).start();
40+
injector.get(WebWorkerSetup).start();
41+
return injector.get(WebWorkerApplication);
3142
});
3243
}
3344

3445
@Injectable()
35-
export class WebWorkerMain {
36-
constructor(public renderCompiler: MessageBasedRenderCompiler,
37-
public renderer: MessageBasedRenderer, public xhr: MessageBasedXHRImpl,
38-
public setup: WebWorkerSetup) {}
46+
export class WebWorkerApplication {
47+
constructor(private _clientMessageBrokerFactory: ClientMessageBrokerFactory,
48+
private _serviceMessageBrokerFactory: ServiceMessageBrokerFactory) {}
49+
50+
createClientMessageBroker(channel: string): ClientMessageBroker {
51+
return this._clientMessageBrokerFactory.createMessageBroker(channel);
52+
}
53+
54+
createServiceMessageBroker(channel: string): ServiceMessageBroker {
55+
return this._serviceMessageBrokerFactory.createMessageBroker(channel);
56+
}
3957
}

modules/angular2/src/web_workers/ui/render_compiler.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ import {ServiceMessageBrokerFactory} from 'angular2/src/web_workers/shared/servi
1313

1414
@Injectable()
1515
export class MessageBasedRenderCompiler {
16-
constructor(brokerFactory: ServiceMessageBrokerFactory, private _renderCompiler: RenderCompiler) {
17-
var broker = brokerFactory.createMessageBroker(RENDER_COMPILER_CHANNEL);
16+
constructor(private _brokerFactory: ServiceMessageBrokerFactory,
17+
private _renderCompiler: RenderCompiler) {}
18+
19+
start(): void {
20+
var broker = this._brokerFactory.createMessageBroker(RENDER_COMPILER_CHANNEL);
1821
broker.registerMethod("compileHost", [RenderDirectiveMetadata],
1922
bind(this._renderCompiler.compileHost, this._renderCompiler),
2023
ProtoViewDto);

modules/angular2/src/web_workers/ui/renderer.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ import {ServiceMessageBrokerFactory} from 'angular2/src/web_workers/shared/servi
1919

2020
@Injectable()
2121
export class MessageBasedRenderer {
22-
constructor(brokerFactory: ServiceMessageBrokerFactory, private _bus: MessageBus,
22+
constructor(private _brokerFactory: ServiceMessageBrokerFactory, private _bus: MessageBus,
2323
private _serializer: Serializer,
2424
private _renderViewWithFragmentsStore: RenderViewWithFragmentsStore,
25-
private _renderer: Renderer) {
26-
var broker = brokerFactory.createMessageBroker(RENDERER_CHANNEL);
25+
private _renderer: Renderer) {}
26+
27+
start(): void {
28+
var broker = this._brokerFactory.createMessageBroker(RENDERER_CHANNEL);
2729
broker.registerMethod("createRootHostView",
2830
[RenderProtoViewRef, PRIMITIVE, PRIMITIVE, PRIMITIVE],
2931
bind(this._createRootHostView, this));

modules/angular2/src/web_workers/ui/setup.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,19 @@ import {StringWrapper} from 'angular2/src/core/facade/lang';
77

88
@Injectable()
99
export class WebWorkerSetup {
10-
constructor(bus: MessageBus, anchorBasedAppRootUrl: AnchorBasedAppRootUrl) {
11-
var rootUrl = anchorBasedAppRootUrl.value;
12-
var sink = bus.to(SETUP_CHANNEL);
13-
var source = bus.from(SETUP_CHANNEL);
10+
rootUrl: string;
11+
12+
constructor(private _bus: MessageBus, anchorBasedAppRootUrl: AnchorBasedAppRootUrl) {
13+
this.rootUrl = anchorBasedAppRootUrl.value;
14+
}
15+
16+
start(): void {
17+
var sink = this._bus.to(SETUP_CHANNEL);
18+
var source = this._bus.from(SETUP_CHANNEL);
1419

1520
ObservableWrapper.subscribe(source, (message: string) => {
1621
if (StringWrapper.equals(message, "ready")) {
17-
ObservableWrapper.callNext(sink, {"rootUrl": rootUrl});
22+
ObservableWrapper.callNext(sink, {"rootUrl": this.rootUrl});
1823
}
1924
});
2025
}

modules/angular2/src/web_workers/ui/xhr_impl.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import {bind} from './bind';
77

88
@Injectable()
99
export class MessageBasedXHRImpl {
10-
constructor(brokerFactory: ServiceMessageBrokerFactory, private _xhr: XHR) {
11-
var broker = brokerFactory.createMessageBroker(XHR_CHANNEL);
10+
constructor(private _brokerFactory: ServiceMessageBrokerFactory, private _xhr: XHR) {}
11+
12+
start(): void {
13+
var broker = this._brokerFactory.createMessageBroker(XHR_CHANNEL);
1214
broker.registerMethod("get", [PRIMITIVE], bind(this._xhr.get, this._xhr), PRIMITIVE);
1315
}
1416
}

0 commit comments

Comments
 (0)