refactor(WebWorker): Use the new generic bootstrap.
BREAKING CHANGE:
You can no longer bootstrap a WebWorker or Isolate using `bootstrap` or `bootstrapWebWorker`. Instead you have to do the following:
In TypeScript:
```TypeScript
// index.js
import {WORKER_RENDER_PLATFORM, WORKER_RENDER_APPLICATION, WORKER_SCRIPT} from "angular2/platforms/worker_render";
import {platform} from "angular2/platform";
platform([WORKER_RENDER_PLATFORM])
.application([WORKER_RENDER_APPLICATION, new Provider(WORKER_SCRIPT, {useValue: "loader.js"});
```
```JavaScript
// loader.js
importScripts("https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.33.3/es6-shim.js", "https://jspm.io/system@0.16.js", "angular2/web_worker/worker.js");
System.import("app");
```
```TypeScript
// app.ts
import {Component, View} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platforms/worker_app";
import {platform} from "angular2/platform";
@Component({
selector: "hello-world"
})
@View({
template: "<h1>Hello {{name}}</h1>
})
export class HelloWorld {
name: string = "Jane";
}
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupWebWorker, optionalProviders?)
.then((ref) => ref.bootstrap(RootComponent));
```
In Dart:
```Dart
// index.dart
import "angular2/platform.dart";
import "angular2/platforms/worker_render.dart";
main() {
platform([WORKER_RENDER_PLATFORM])
.asyncApplication(initIsolate("my_worker.dart"));
}
```
```Dart
// background_index.dart
import "angular2/platform.dart";
import "angular2/platforms/worker_app.dart";
import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart";
@Component(
selector: "hello-world"
)
@View(
template: "<h1>Hello {{name}}</h1>"
)
class HelloWorld {
String name = "Jane";
}
main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities();
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupIsolate(replyTo))
.then((ref) => ref.bootstrap(RootComponent));
}
```
You should no longer import from the `angular2/web_worker/worker` and `angular2/web_worker/ui` paths. Instead you can now import directly from core, directives, etc..
The WebWorkerApplication class has been removed. If you want to use ServiceMessageBroker or ClientMessageBroker on the render thread, you must inject their factories via DI.
If you need to use the MessageBus on the render thread you must also obtain it through DI.
closes #3277
closes #5473
Closes #5519
This commit is contained in:
@@ -1,56 +0,0 @@
|
||||
library angular2.src.web_workers.ui;
|
||||
|
||||
import 'dart:isolate';
|
||||
import 'dart:async';
|
||||
import 'dart:core';
|
||||
import 'package:angular2/src/web_workers/shared/message_bus.dart'
|
||||
show MessageBus;
|
||||
import 'package:angular2/src/web_workers/ui/impl.dart'
|
||||
show bootstrapUICommon, WebWorkerApplication;
|
||||
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
|
||||
|
||||
/**
|
||||
* Bootstrapping a WebWorker
|
||||
*
|
||||
* You instantiate a WebWorker application by calling bootstrap with the URI of your worker's index script
|
||||
* Note: The WebWorker script must call bootstrapWebworker once it is set up to complete the bootstrapping process
|
||||
*/
|
||||
Future<IsolateInstance> bootstrap(String uri) async {
|
||||
var instance = await spawnWebWorker(Uri.parse(uri));
|
||||
instance.app = bootstrapUICommon(instance.bus);
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called from the main thread to spawn and communicate with the worker thread
|
||||
*/
|
||||
Future<IsolateInstance> spawnWebWorker(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 IsolateInstance(null, 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 {@link WebWorkerApplication}
|
||||
* Isolate instance and underlying {@link MessageBus} for lower level message passing.
|
||||
*/
|
||||
class IsolateInstance {
|
||||
WebWorkerApplication app;
|
||||
final Isolate isolate;
|
||||
final MessageBus bus;
|
||||
|
||||
IsolateInstance(this.app, this.isolate, this.bus);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import {
|
||||
PostMessageBus,
|
||||
PostMessageBusSink,
|
||||
PostMessageBusSource
|
||||
} from 'angular2/src/web_workers/shared/post_message_bus';
|
||||
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
import {bootstrapUICommon, WebWorkerApplication} from 'angular2/src/web_workers/ui/impl';
|
||||
export {WebWorkerApplication} from 'angular2/src/web_workers/ui/impl';
|
||||
export * from 'angular2/src/web_workers/shared/message_bus';
|
||||
|
||||
/**
|
||||
* Bootstrapping a WebWorker
|
||||
*
|
||||
* You instantiate a WebWorker application by calling bootstrap with the URI of your worker's index
|
||||
* script
|
||||
* Note: The WebWorker script must call bootstrapWebworker once it is set up to complete the
|
||||
* bootstrapping process
|
||||
*/
|
||||
export function bootstrap(uri: string): WebWorkerInstance {
|
||||
var instance = spawnWebWorker(uri);
|
||||
instance.app = bootstrapUICommon(instance.bus);
|
||||
return instance;
|
||||
}
|
||||
|
||||
export function spawnWebWorker(uri: string): WebWorkerInstance {
|
||||
var webWorker: Worker = new Worker(uri);
|
||||
var sink = new PostMessageBusSink(webWorker);
|
||||
var source = new PostMessageBusSource(webWorker);
|
||||
var bus = new PostMessageBus(sink, source);
|
||||
return new WebWorkerInstance(null, webWorker, bus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper class that exposes the {@link WebWorkerApplication}
|
||||
* Isolate instance and underlying {@link MessageBus} for lower level message passing.
|
||||
*/
|
||||
export class WebWorkerInstance {
|
||||
constructor(public app: WebWorkerApplication, public worker: Worker, public bus: MessageBus) {}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
// TODO (jteplitz602): This whole file is nearly identical to core/application.ts.
|
||||
// There should be a way to refactor application so that this file is unnecessary. See #3277
|
||||
import {Injector, provide, Provider} from "angular2/src/core/di";
|
||||
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
||||
import {BrowserDetails} from 'angular2/src/animate/browser_details';
|
||||
import {Reflector, reflector} from 'angular2/src/core/reflection/reflection';
|
||||
import {Parser, Lexer} from 'angular2/src/core/change_detection/change_detection';
|
||||
import {EventManager, EVENT_MANAGER_PLUGINS} from 'angular2/platform/common_dom';
|
||||
import {ProtoViewFactory} from 'angular2/src/core/linker/proto_view_factory';
|
||||
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
|
||||
import {KeyEventsPlugin} from 'angular2/src/platform/dom/events/key_events';
|
||||
import {HammerGesturesPlugin} from 'angular2/src/platform/dom/events/hammer_gestures';
|
||||
import {AppViewPool, APP_VIEW_POOL_CAPACITY} from 'angular2/src/core/linker/view_pool';
|
||||
import {Renderer} from 'angular2/src/core/render/api';
|
||||
import {AppRootUrl} from 'angular2/src/compiler/app_root_url';
|
||||
import {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
||||
import {DomRenderer, DomRenderer_} from 'angular2/src/platform/dom/dom_renderer';
|
||||
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
|
||||
import {APP_ID_RANDOM_PROVIDER} from 'angular2/src/core/application_tokens';
|
||||
import {ElementSchemaRegistry} from 'angular2/src/compiler/schema/element_schema_registry';
|
||||
import {DomElementSchemaRegistry} from 'angular2/src/compiler/schema/dom_element_schema_registry';
|
||||
import {SharedStylesHost, DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {NgZone} from 'angular2/src/core/zone/ng_zone';
|
||||
import {AppViewManager, AppViewManager_} from 'angular2/src/core/linker/view_manager';
|
||||
import {AppViewManagerUtils} from 'angular2/src/core/linker/view_manager_utils';
|
||||
import {AppViewListener} from 'angular2/src/core/linker/view_listener';
|
||||
import {ViewResolver} from 'angular2/src/core/linker/view_resolver';
|
||||
import {DirectiveResolver} from 'angular2/src/core/linker/directive_resolver';
|
||||
import {ExceptionHandler} from 'angular2/src/facade/exceptions';
|
||||
import {
|
||||
DynamicComponentLoader,
|
||||
DynamicComponentLoader_
|
||||
} from 'angular2/src/core/linker/dynamic_component_loader';
|
||||
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
|
||||
import {Testability} from 'angular2/src/core/testability/testability';
|
||||
import {XHR} from 'angular2/src/compiler/xhr';
|
||||
import {XHRImpl} from 'angular2/src/platform/browser/xhr_impl';
|
||||
import {Serializer} from 'angular2/src/web_workers/shared/serializer';
|
||||
import {ON_WEB_WORKER} from 'angular2/src/web_workers/shared/api';
|
||||
import {RenderProtoViewRefStore} from 'angular2/src/web_workers/shared/render_proto_view_ref_store';
|
||||
import {
|
||||
RenderViewWithFragmentsStore
|
||||
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
|
||||
import {AnchorBasedAppRootUrl} from 'angular2/src/compiler/anchor_based_app_root_url';
|
||||
import {WebWorkerApplication} from 'angular2/src/web_workers/ui/impl';
|
||||
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
|
||||
import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer';
|
||||
import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl';
|
||||
import {WebWorkerSetup} from 'angular2/src/web_workers/ui/setup';
|
||||
import {
|
||||
ServiceMessageBrokerFactory,
|
||||
ServiceMessageBrokerFactory_
|
||||
} from 'angular2/src/web_workers/shared/service_message_broker';
|
||||
import {
|
||||
ClientMessageBrokerFactory,
|
||||
ClientMessageBrokerFactory_
|
||||
} from 'angular2/src/web_workers/shared/client_message_broker';
|
||||
import {PLATFORM_DIRECTIVES, PLATFORM_PIPES} from "angular2/src/core/platform_directives_and_pipes";
|
||||
import {COMMON_DIRECTIVES, COMMON_PIPES} from "angular2/common";
|
||||
|
||||
var _rootInjector: Injector;
|
||||
|
||||
// Contains everything that is safe to share between applications.
|
||||
var _rootProviders = [provide(Reflector, {useValue: reflector})];
|
||||
|
||||
// TODO: This code is nearly identical to core/application. There should be a way to only write it
|
||||
// once
|
||||
function _injectorProviders(): any[] {
|
||||
return [
|
||||
provide(DOCUMENT, {useValue: DOM.defaultDoc()}),
|
||||
EventManager,
|
||||
new Provider(EVENT_MANAGER_PLUGINS, {useClass: DomEventsPlugin, multi: true}),
|
||||
new Provider(EVENT_MANAGER_PLUGINS, {useClass: KeyEventsPlugin, multi: true}),
|
||||
new Provider(EVENT_MANAGER_PLUGINS, {useClass: HammerGesturesPlugin, multi: true}),
|
||||
provide(DomRenderer, {useClass: DomRenderer_}),
|
||||
provide(Renderer, {useExisting: DomRenderer}),
|
||||
APP_ID_RANDOM_PROVIDER,
|
||||
DomSharedStylesHost,
|
||||
provide(SharedStylesHost, {useExisting: DomSharedStylesHost}),
|
||||
Serializer,
|
||||
provide(ON_WEB_WORKER, {useValue: false}),
|
||||
provide(ElementSchemaRegistry, {useValue: new DomElementSchemaRegistry()}),
|
||||
RenderViewWithFragmentsStore,
|
||||
RenderProtoViewRefStore,
|
||||
AppViewPool,
|
||||
provide(APP_VIEW_POOL_CAPACITY, {useValue: 10000}),
|
||||
provide(AppViewManager, {useClass: AppViewManager_}),
|
||||
AppViewManagerUtils,
|
||||
AppViewListener,
|
||||
ProtoViewFactory,
|
||||
ViewResolver,
|
||||
provide(PLATFORM_PIPES, {useValue: COMMON_PIPES, multi: true}),
|
||||
provide(PLATFORM_DIRECTIVES, {useValue: COMMON_DIRECTIVES, multi: true}),
|
||||
DirectiveResolver,
|
||||
Parser,
|
||||
Lexer,
|
||||
provide(ExceptionHandler, {useFactory: () => new ExceptionHandler(DOM), deps: []}),
|
||||
provide(XHR, {useValue: new XHRImpl()}),
|
||||
UrlResolver,
|
||||
provide(DynamicComponentLoader, {useClass: DynamicComponentLoader_}),
|
||||
Testability,
|
||||
AnchorBasedAppRootUrl,
|
||||
provide(AppRootUrl, {useExisting: AnchorBasedAppRootUrl}),
|
||||
WebWorkerApplication,
|
||||
WebWorkerSetup,
|
||||
MessageBasedXHRImpl,
|
||||
MessageBasedRenderer,
|
||||
provide(ServiceMessageBrokerFactory, {useClass: ServiceMessageBrokerFactory_}),
|
||||
provide(ClientMessageBrokerFactory, {useClass: ClientMessageBrokerFactory_}),
|
||||
BrowserDetails,
|
||||
AnimationBuilder
|
||||
];
|
||||
}
|
||||
|
||||
export function createInjector(zone: NgZone, bus: MessageBus): Injector {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
_rootProviders.push(provide(NgZone, {useValue: zone}));
|
||||
_rootProviders.push(provide(MessageBus, {useValue: bus}));
|
||||
var injector: Injector = Injector.resolveAndCreate(_rootProviders);
|
||||
return injector.resolveAndCreateChild(_injectorProviders());
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* This file is the entry point for the main thread
|
||||
* It takes care of spawning the worker and sending it the initial init message
|
||||
* It also acts and the messenger between the worker thread and the renderer running on the UI
|
||||
* thread
|
||||
*/
|
||||
|
||||
import {createInjector} from "./di_bindings";
|
||||
import {MessageBus, MessageBusSink} from "angular2/src/web_workers/shared/message_bus";
|
||||
import {createNgZone} from 'angular2/src/core/application_ref';
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
|
||||
import {wtfInit} from 'angular2/src/core/profile/wtf_init';
|
||||
import {WebWorkerSetup} from 'angular2/src/web_workers/ui/setup';
|
||||
import {MessageBasedRenderer} from 'angular2/src/web_workers/ui/renderer';
|
||||
import {MessageBasedXHRImpl} from 'angular2/src/web_workers/ui/xhr_impl';
|
||||
import {
|
||||
ClientMessageBrokerFactory,
|
||||
ClientMessageBroker,
|
||||
} from 'angular2/src/web_workers/shared/client_message_broker';
|
||||
import {
|
||||
ServiceMessageBrokerFactory,
|
||||
ServiceMessageBroker
|
||||
} from 'angular2/src/web_workers/shared/service_message_broker';
|
||||
|
||||
/**
|
||||
* Creates a zone, sets up the DI providers
|
||||
* And then creates a new WebWorkerMain object to handle messages from the worker
|
||||
*/
|
||||
export function bootstrapUICommon(bus: MessageBus): WebWorkerApplication {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
var zone = createNgZone();
|
||||
wtfInit();
|
||||
bus.attachToZone(zone);
|
||||
return zone.run(() => {
|
||||
var injector = createInjector(zone, bus);
|
||||
injector.get(MessageBasedRenderer).start();
|
||||
injector.get(MessageBasedXHRImpl).start();
|
||||
injector.get(WebWorkerSetup).start();
|
||||
return injector.get(WebWorkerApplication);
|
||||
});
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class WebWorkerApplication {
|
||||
constructor(private _clientMessageBrokerFactory: ClientMessageBrokerFactory,
|
||||
private _serviceMessageBrokerFactory: ServiceMessageBrokerFactory) {}
|
||||
|
||||
createClientMessageBroker(channel: string, runInZone: boolean = true): ClientMessageBroker {
|
||||
return this._clientMessageBrokerFactory.createMessageBroker(channel, runInZone);
|
||||
}
|
||||
|
||||
createServiceMessageBroker(channel: string, runInZone: boolean = true): ServiceMessageBroker {
|
||||
return this._serviceMessageBrokerFactory.createMessageBroker(channel, runInZone);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user