Skip to content

Commit

Permalink
1710272 refactor(WebWorker): Use the new generic bootstrap.
Browse files Browse the repository at this point in the history
  • Loading branch information
jteplitz committed Dec 3, 2015
1 parent 749fc92 commit eaadbe4
Show file tree
Hide file tree
Showing 22 changed files with 1,077 additions and 1,122 deletions.
4 changes: 2 additions & 2 deletions BUILD_INFO
@@ -1,2 +1,2 @@
Thu Dec 3 19:44:52 UTC 2015
93a1ec29e12357fec1091e835f7eab51b299bd92
Thu Dec 3 20:05:06 UTC 2015
1710272b3cb71576fb251a85277c901893e06f7c
999 changes: 500 additions & 499 deletions _analyzer.dart

Large diffs are not rendered by default.

214 changes: 144 additions & 70 deletions docs/web_workers/web_workers.md

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions lib/platform/worker_app.dart
@@ -0,0 +1,11 @@
library angular2.platform.worker_app;

export "package:angular2/src/platform/worker_app_common.dart"
show WORKER_APP_PLATFORM, genericWorkerAppProviders;
export "package:angular2/src/platform/worker_app.dart";
export "../src/web_workers/shared/client_message_broker.dart"
show ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments;
export "../src/web_workers/shared/service_message_broker.dart"
show ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory;
export "../src/web_workers/shared/serializer.dart" show PRIMITIVE;
export "../src/web_workers/shared/message_bus.dart";
20 changes: 20 additions & 0 deletions lib/platform/worker_render.dart
@@ -0,0 +1,20 @@
library angular2.platform.worker_render;

export 'package:angular2/src/platform/worker_render_common.dart'
show
WORKER_SCRIPT,
WORKER_RENDER_PLATFORM,
WORKER_RENDER_APP_COMMON,
initializeGenericWorkerRenderer;

export 'package:angular2/src/platform/worker_render.dart'
show WORKER_RENDER_APP, initIsolate, WebWorkerInstance;

export '../src/web_workers/shared/client_message_broker.dart'
show ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments;

export '../src/web_workers/shared/service_message_broker.dart'
show ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory;

export '../src/web_workers/shared/serializer.dart' show PRIMITIVE;
export '../src/web_workers/shared/message_bus.dart';
12 changes: 8 additions & 4 deletions lib/src/core/application_ref.dart
Expand Up @@ -187,9 +187,8 @@ abstract class PlatformRef {
* constructed in the same manner as a normal `application()`.
*/
Future<ApplicationRef> asyncApplication(
dynamic /* (zone: NgZone) =>
Promise<Array<Type | Provider | any[]>> */
bindingFn);
dynamic /* (zone: NgZone) => Promise<Array<Type | Provider | any[]>> */ bindingFn,
[List<dynamic /* Type | Provider | List < dynamic > */ > providers]);
/**
* Destroy the Angular platform and all Angular applications on the page.
*/
Expand Down Expand Up @@ -221,12 +220,17 @@ class PlatformRef_ extends PlatformRef {
}

Future<ApplicationRef> asyncApplication(
dynamic /* (zone: NgZone) => Promise<Array<Type | Provider | any[]>> */ bindingFn) {
dynamic /* (zone: NgZone) => Promise<Array<Type | Provider | any[]>> */ bindingFn,
[List<
dynamic /* Type | Provider | List < dynamic > */ > additionalProviders]) {
var zone = createNgZone();
var completer = PromiseWrapper.completer();
zone.run(() {
PromiseWrapper.then(bindingFn(zone),
(List<dynamic /* Type | Provider | List < dynamic > */ > providers) {
if (isPresent(additionalProviders)) {
providers = ListWrapper.concat(providers, additionalProviders);
}
completer.resolve(this._initApp(zone, providers));
});
});
Expand Down
25 changes: 25 additions & 0 deletions lib/src/platform/worker_app.dart
@@ -0,0 +1,25 @@
library angular2.src.platform.worker_app;

import 'package:angular2/src/core/zone/ng_zone.dart';
import 'package:angular2/src/platform/server/webworker_adapter.dart';
import 'package:angular2/src/platform/worker_app_common.dart';
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
import 'dart:isolate';

setupIsolate(SendPort replyTo) {
return (NgZone zone) {
WebWorkerDomAdapter.makeCurrent();

ReceivePort rPort = new ReceivePort();
var sink = new WebWorkerMessageBusSink(replyTo, rPort);
var source = new IsolateMessageBusSource(rPort);
IsolateMessageBus bus = new IsolateMessageBus(sink, source);
return genericWorkerAppProviders(bus, zone);
};
}

class WebWorkerMessageBusSink extends IsolateMessageBusSink {
WebWorkerMessageBusSink(SendPort sPort, ReceivePort rPort) : super(sPort) {
sPort.send(rPort.sendPort);
}
}
104 changes: 104 additions & 0 deletions lib/src/platform/worker_app_common.dart
@@ -0,0 +1,104 @@
library angular2.src.platform.worker_app_common;

import "package:angular2/src/compiler/xhr.dart" show XHR;
import "package:angular2/src/web_workers/worker/xhr_impl.dart"
show WebWorkerXHRImpl;
import "package:angular2/src/facade/collection.dart" show ListWrapper;
import "package:angular2/src/compiler/app_root_url.dart" show AppRootUrl;
import "package:angular2/src/web_workers/worker/renderer.dart"
show WebWorkerRenderer;
import "package:angular2/src/facade/lang.dart" show print, Type, isPresent;
import "package:angular2/src/web_workers/shared/message_bus.dart"
show MessageBus;
import "package:angular2/src/core/render/api.dart" show Renderer;
import "package:angular2/core.dart"
show
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
ExceptionHandler,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS;
import "package:angular2/common.dart"
show COMMON_DIRECTIVES, COMMON_PIPES, FORM_PROVIDERS;
import "package:angular2/src/web_workers/shared/client_message_broker.dart"
show ClientMessageBrokerFactory, ClientMessageBrokerFactory_;
import "package:angular2/src/web_workers/shared/service_message_broker.dart"
show ServiceMessageBrokerFactory, ServiceMessageBrokerFactory_;
import "package:angular2/src/compiler/compiler.dart" show COMPILER_PROVIDERS;
import "package:angular2/src/web_workers/shared/serializer.dart"
show Serializer;
import "package:angular2/src/web_workers/shared/api.dart" show ON_WEB_WORKER;
import "package:angular2/src/core/di.dart" show Provider;
import "package:angular2/src/web_workers/shared/render_proto_view_ref_store.dart"
show RenderProtoViewRefStore;
import "package:angular2/src/web_workers/shared/render_view_with_fragments_store.dart"
show RenderViewWithFragmentsStore;
import "package:angular2/src/web_workers/worker/event_dispatcher.dart"
show WebWorkerEventDispatcher;
import "package:angular2/src/core/zone/ng_zone.dart" show NgZone;
import "package:angular2/src/facade/async.dart"
show Future, PromiseWrapper, PromiseCompleter;
import "package:angular2/src/web_workers/shared/messaging_api.dart"
show SETUP_CHANNEL;
import "package:angular2/src/facade/async.dart" show ObservableWrapper;

class PrintLogger {
var log = print;
var logError = print;
var logGroup = print;
logGroupEnd() {}
}

const List<dynamic> WORKER_APP_PLATFORM = const [PLATFORM_COMMON_PROVIDERS];
const List<dynamic> WORKER_APP_COMMON_PROVIDERS = const [
APPLICATION_COMMON_PROVIDERS,
COMPILER_PROVIDERS,
FORM_PROVIDERS,
Serializer,
const Provider(PLATFORM_PIPES, useValue: COMMON_PIPES, multi: true),
const Provider(PLATFORM_DIRECTIVES, useValue: COMMON_DIRECTIVES, multi: true),
const Provider(ClientMessageBrokerFactory,
useClass: ClientMessageBrokerFactory_),
const Provider(ServiceMessageBrokerFactory,
useClass: ServiceMessageBrokerFactory_),
WebWorkerRenderer,
const Provider(Renderer, useExisting: WebWorkerRenderer),
const Provider(ON_WEB_WORKER, useValue: true),
RenderViewWithFragmentsStore,
RenderProtoViewRefStore,
const Provider(ExceptionHandler,
useFactory: _exceptionHandler, deps: const []),
WebWorkerXHRImpl,
const Provider(XHR, useExisting: WebWorkerXHRImpl),
WebWorkerEventDispatcher
];
ExceptionHandler _exceptionHandler() {
return new ExceptionHandler(new PrintLogger());
}

/**
* Asynchronously returns a list of providers that can be used to initialize the
* Application injector.
* Also takes care of attaching the [MessageBus] to the given [NgZone].
*/
Future<
List<
dynamic /* Type | Provider | List < dynamic > */ >> genericWorkerAppProviders(
MessageBus bus, NgZone zone) {
PromiseCompleter<dynamic> bootstrapProcess = PromiseWrapper.completer();
bus.attachToZone(zone);
bus.initChannel(SETUP_CHANNEL, false);
dynamic subscription;
var emitter = bus.from(SETUP_CHANNEL);
subscription = ObservableWrapper.subscribe(emitter,
(Map<String, dynamic> initData) {
var bindings = ListWrapper.concat(WORKER_APP_COMMON_PROVIDERS, [
new Provider(MessageBus, useValue: bus),
new Provider(AppRootUrl, useValue: new AppRootUrl(initData["rootUrl"]))
]);
bootstrapProcess.resolve(bindings);
ObservableWrapper.dispose(subscription);
});
ObservableWrapper.callNext(bus.to(SETUP_CHANNEL), "ready");
return bootstrapProcess.promise;
}
69 changes: 69 additions & 0 deletions lib/src/platform/worker_render.dart
@@ -0,0 +1,69 @@
library angular2.src.platform.worker_render;

import 'package:angular2/src/platform/worker_render_common.dart'
show
WORKER_RENDER_APP_COMMON,
WORKER_RENDER_MESSAGING_PROVIDERS,
WORKER_SCRIPT,
initializeGenericWorkerRenderer;
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
import 'package:angular2/src/web_workers/shared/message_bus.dart';
import 'package:angular2/core.dart';
import 'package:angular2/src/core/di.dart';
import 'package:angular2/src/core/zone/ng_zone.dart';
import 'dart:isolate';
import 'dart:async';

const WORKER_RENDER_APP = WORKER_RENDER_APP_COMMON;

initIsolate(String scriptUri) {
return (NgZone zone) async {
var instance = await spawnIsolate(Uri.parse(scriptUri));

return [
WORKER_RENDER_APP_COMMON,
new Provider(WebWorkerInstance, useValue: instance),
new Provider(APP_INITIALIZER,
useFactory: (injector) =>
() => initializeGenericWorkerRenderer(injector),
multi: true,
deps: [Injector]),
new Provider(MessageBus, useValue: instance.bus)
];
};
}

/**
* Spawns a new class and initializes the WebWorkerInstance
*/
Future<WebWorkerInstance> spawnIsolate(Uri uri) async {
var receivePort = new ReceivePort();
var isolateEndSendPort = receivePort.sendPort;
var isolate = await Isolate.spawnUri(uri, const [], isolateEndSendPort);
var source = new UIMessageBusSource(receivePort);
var sendPort = await source.sink;
var sink = new IsolateMessageBusSink(sendPort);
var bus = new IsolateMessageBus(sink, source);

return new WebWorkerInstance(isolate, bus);
}

class UIMessageBusSource extends IsolateMessageBusSource {
UIMessageBusSource(ReceivePort port) : super(port);

Future<SendPort> get sink => stream.firstWhere((message) {
return message is SendPort;
});
}

/**
* Wrapper class that exposes the Isolate
* and underlying {@link MessageBus} for lower level message passing.
*/
@Injectable()
class WebWorkerInstance {
Isolate worker;
MessageBus bus;

WebWorkerInstance(this.worker, this.bus);
}
121 changes: 121 additions & 0 deletions lib/src/platform/worker_render_common.dart
@@ -0,0 +1,121 @@
library angular2.src.platform.worker_render_common;

import "package:angular2/src/web_workers/shared/message_bus.dart"
show MessageBus;
import "package:angular2/src/core/zone/ng_zone.dart" show NgZone;
import "package:angular2/src/compiler/anchor_based_app_root_url.dart"
show AnchorBasedAppRootUrl;
import "package:angular2/src/compiler/app_root_url.dart" show AppRootUrl;
import "package:angular2/core.dart"
show
PLATFORM_DIRECTIVES,
PLATFORM_PIPES,
ComponentRef,
platform,
ExceptionHandler,
Reflector,
reflector,
APPLICATION_COMMON_PROVIDERS,
PLATFORM_COMMON_PROVIDERS,
Renderer,
PLATFORM_INITIALIZER,
APP_INITIALIZER;
import "package:angular2/platform/common_dom.dart"
show EVENT_MANAGER_PLUGINS, EventManager;
import "package:angular2/src/core/di.dart"
show provide, Provider, Injector, OpaqueToken;
// TODO change these imports once dom_adapter is moved out of core
import "package:angular2/src/platform/dom/dom_adapter.dart" show DOM;
import "package:angular2/src/platform/dom/events/dom_events.dart"
show DomEventsPlugin;
import "package:angular2/src/platform/dom/events/key_events.dart"
show KeyEventsPlugin;
import "package:angular2/src/platform/dom/events/hammer_gestures.dart"
show HammerGesturesPlugin;
import "package:angular2/src/platform/dom/dom_tokens.dart" show DOCUMENT;
import "package:angular2/src/platform/dom/dom_renderer.dart"
show DomRenderer, DomRenderer_;
import "package:angular2/src/platform/dom/shared_styles_host.dart"
show DomSharedStylesHost;
import "package:angular2/src/platform/dom/shared_styles_host.dart"
show SharedStylesHost;
import "package:angular2/src/animate/browser_details.dart" show BrowserDetails;
import "package:angular2/src/animate/animation_builder.dart"
show AnimationBuilder;
import "package:angular2/compiler.dart" show XHR;
import "package:angular2/src/platform/browser/xhr_impl.dart" show XHRImpl;
import "package:angular2/src/core/testability/testability.dart"
show Testability;
import "package:angular2/src/platform/browser/testability.dart"
show BrowserGetTestability;
import "browser/browser_adapter.dart" show BrowserDomAdapter;
import "package:angular2/src/core/profile/wtf_init.dart" show wtfInit;
import "package:angular2/src/web_workers/ui/setup.dart" show WebWorkerSetup;
import "package:angular2/src/web_workers/ui/renderer.dart"
show MessageBasedRenderer;
import "package:angular2/src/web_workers/ui/xhr_impl.dart"
show MessageBasedXHRImpl;
import "package:angular2/src/web_workers/shared/service_message_broker.dart"
show ServiceMessageBrokerFactory, ServiceMessageBrokerFactory_;
import "package:angular2/src/web_workers/shared/client_message_broker.dart"
show ClientMessageBrokerFactory, ClientMessageBrokerFactory_;
import "package:angular2/src/web_workers/shared/serializer.dart"
show Serializer;
import "package:angular2/src/web_workers/shared/api.dart" show ON_WEB_WORKER;
import "package:angular2/src/web_workers/shared/render_proto_view_ref_store.dart"
show RenderProtoViewRefStore;
import "package:angular2/src/web_workers/shared/render_view_with_fragments_store.dart"
show RenderViewWithFragmentsStore;

const OpaqueToken WORKER_SCRIPT = const OpaqueToken("WebWorkerScript");
// Message based Worker classes that listen on the MessageBus
const List<dynamic> WORKER_RENDER_MESSAGING_PROVIDERS = const [
MessageBasedRenderer,
MessageBasedXHRImpl,
WebWorkerSetup
];
const List<dynamic> WORKER_RENDER_PLATFORM = const [
PLATFORM_COMMON_PROVIDERS,
const Provider(PLATFORM_INITIALIZER,
useValue: initWebWorkerRenderPlatform, multi: true)
];
const List<dynamic> WORKER_RENDER_APP_COMMON = const [
APPLICATION_COMMON_PROVIDERS, WORKER_RENDER_MESSAGING_PROVIDERS,
const Provider(ExceptionHandler,
useFactory: _exceptionHandler, deps: const []),
const Provider(DOCUMENT, useFactory: _document, deps: const []),
// TODO(jteplitz602): Investigate if we definitely need EVENT_MANAGER on the render thread

// #5298
const Provider(EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true), const Provider(EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true), const Provider(EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true), const Provider(DomRenderer, useClass: DomRenderer_), const Provider(Renderer, useExisting: DomRenderer),
const Provider(SharedStylesHost, useExisting: DomSharedStylesHost), const Provider(XHR, useClass: XHRImpl), MessageBasedXHRImpl,
const Provider(ServiceMessageBrokerFactory, useClass: ServiceMessageBrokerFactory_),
const Provider(ClientMessageBrokerFactory, useClass: ClientMessageBrokerFactory_),
AnchorBasedAppRootUrl, const Provider(AppRootUrl, useExisting: AnchorBasedAppRootUrl), Serializer,
const Provider(ON_WEB_WORKER, useValue: false), RenderViewWithFragmentsStore, RenderProtoViewRefStore,
DomSharedStylesHost, Testability, BrowserDetails, AnimationBuilder, EventManager
];
initializeGenericWorkerRenderer(Injector injector) {
var bus = injector.get(MessageBus);
var zone = injector.get(NgZone);
bus.attachToZone(zone);
zone.run(() {
WORKER_RENDER_MESSAGING_PROVIDERS.forEach((token) {
injector.get(token).start();
});
});
}

void initWebWorkerRenderPlatform() {
BrowserDomAdapter.makeCurrent();
wtfInit();
BrowserGetTestability.init();
}

ExceptionHandler _exceptionHandler() {
return new ExceptionHandler(DOM, false);
}

dynamic _document() {
return DOM.defaultDoc();
}

0 comments on commit eaadbe4

Please sign in to comment.