refactor(WebWorker): Make WebWorker bootstrap synchronous

BREAKING CHANGE

From the app thread, in both TypeScript and Dart, you bootstrap the app
using `application` instead of `asyncApplication`.
Before:
```TypeScript
platform([WORKER_APP_PLATFORM])
.asyncApplication(setupWebWorker, optionalProviders?)
.then((ref) => ref.bootstrap(RootComponent));
```
Now:
```TypeScript
platform([WORKER_APP_PLATFORM])
.application([WORKER_APP_APPLICATION])
.bootstrap(RootComponent);
```

closes #5857

Closes #5862
This commit is contained in:
Jason Teplitz 2015-12-13 00:47:49 -05:00
parent 4deaf0bdd3
commit 006a96dd20
18 changed files with 140 additions and 123 deletions

View File

@ -55,7 +55,7 @@ System.import("app");
```TypeScript ```TypeScript
// app.ts // app.ts
import {Component, View, platform} from "angular2/core"; import {Component, View, platform} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platform/worker_app"; import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app";
@Component({ @Component({
selector: "hello-world" selector: "hello-world"
@ -68,7 +68,7 @@ export class HelloWorld {
} }
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM])
.asyncApplication(setupWebWorker, optionalProviders?) .application([WORKER_APP_APPLICATION])
.then((ref) => ref.bootstrap(RootComponent)); .then((ref) => ref.bootstrap(RootComponent));
``` ```
There's a few important things to note here: There's a few important things to note here:
@ -125,26 +125,26 @@ class HelloWorld {
main(List<String> args, SendPort replyTo) { main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities(); reflector.reflectionCapabilities = new ReflectionCapabilities();
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM, new Provider(RENDER_SEND_PORT, useValue: replyTo)])
.asyncApplication(setupIsolate(replyTo)) .application([WORKER_APP_APPLICATION])
.then((ref) => ref.bootstrap(RootComponent)); .bootstrap(RootComponent);
} }
``` ```
This code is nearly the same as the TypeScript version with just a couple key differences: This code is nearly the same as the TypeScript version with just a couple key differences:
* We don't have a `loader.js` file. Dart applications don't need this file because you don't need a module loader. * We don't have a `loader.js` file. Dart applications don't need this file because you don't need a module loader.
* We pass a `SendPort` to `bootstrapWebWorker`. Dart applications use the Isolate API, which communicates via * We provide a `SendPort` through DI using the token `RENDER_SEND_PORT`. Dart applications use the Isolate API, which communicates via
Dart's Port abstraction. When you call `setupIsolate` from the UI thread, angular starts a new Isolate to run Dart's Port abstraction. When you call `setupIsolate` from the UI thread, angular starts a new Isolate to run
your application logic. When Dart starts a new Isolate it passes a `SendPort` to that Isolate so that it your application logic. When Dart starts a new Isolate it passes a `SendPort` to that Isolate so that it
can communicate with the Isolate that spawned it. You need to pass this `SendPort` to `bootstrapWebWorker` can communicate with the Isolate that spawned it. You need to provide this `SendPort` through DI
so that Angular can communicate with the UI. so that Angular can communicate with the UI.
* You need to set up `ReflectionCapabilities` on both the UI and Worker. Just like writing non-concurrent * You need to set up `ReflectionCapabilities` on both the UI and Worker. Just like writing non-concurrent
Angular2 Dart applications you need to set up the reflector. You should not use Reflection in production, Angular2 Dart applications you need to set up the reflector. You should not use Reflection in production,
but should use the angular 2 transformer to remove it in your final JS code. Note there's currently a bug but should use the angular 2 transformer to remove it in your final JS code. Note there's currently a bug
with running the transformer on your UI code (#3971). You can (and should) pass the file where you call with running the transformer on your UI code (#3971). You can (and should) pass the file where you call
`bootstrapWebWorker` as an entry point to the transformer, but you should not pass your UI index file `bootstrap` as an entry point to the transformer, but you should not pass your UI index file
to the transformer until that bug is fixed. to the transformer until that bug is fixed.
* In dart we call `asyncApplication` instead of `application` because starting an isolate in Dart is asyncronous * In dart we call `asyncApplication` instead of `application` from the render thread because starting an isolate in Dart is asyncronous
whereas starting a new WebWorker in JavaScript is a synchronous operation. whereas starting a new WebWorker in JavaScript is a synchronous operation.
## Writing WebWorker Compatible Components ## Writing WebWorker Compatible Components
@ -392,18 +392,22 @@ import {WORKER_APP_PLATFORM, genericWorkerAppProviders} from "angular2/platform/
import {NgZone, platform, Provider} from "angular/core"; import {NgZone, platform, Provider} from "angular/core";
import {MyApp} from './app'; import {MyApp} from './app';
platform([WORKER_APP_PLATFORM_PROVIDERS])
.asyncApplication(initAppThread, optionalProviders?)
.then((ref) => ref.bootstrap(MyApp));
function initAppThread(zone: NgZone): Promise<Array<Type | Provider | any[]>> {
/** /**
* Do initializtion work here to set up the app thread and MessageBus * Do initialization work here to set up the app thread and MessageBus;
* Once you have a working MessageBus that communicates with the render thread you should call genericWorkerAppProviders * Once you have a working MessageBus you should bootstrap your app.
* to get a list of Providers. */
platform([WORKER_APP_PLATFORM_PROVIDERS])
.application([WORKER_APP_APPLICATION_COMMON, new Provider(MessageBus, {useValue: bus}),
new Provider(APP_INITIALIZER, {useFactory: (zone, bus) => () => initAppThread(zone, bus), multi: true, deps: [NgZone, MessageBus]})])
.bootstrap(MyApp);
function initAppThread(zone: NgZone, bus: MyAwesomeMessageBus): void{
/**
* Here you can do any initilization work that requires the app providers to be initialized.
* At a minimum, you must attach your bus to the zone and setup a DOM adapter.
* Depending on your environment you may choose to do more work here.
*/ */
var bus = new MyAwesomeMessageBus();
return genericWorkerAppProviders(myBus, zone);
} }
``` ```
In Dart: In Dart:
@ -432,27 +436,30 @@ import "package:angular2/core.dart";
import "./app.dart" show MyApp; import "./app.dart" show MyApp;
main() { main() {
/**
* Do initialization work here to set up the app thread and MessageBus;
* Once you have a working MessageBus you should bootstrap your app.
*/
reflector.reflectionCapabilities = new ReflectionCapabilities(); reflector.reflectionCapabilities = new ReflectionCapabilities();
platform([WORKER_APP_PLATFORM_PROVIDERS]) platform([WORKER_APP_PLATFORM_PROVIDERS])
.asyncApplication(initAppThread, optionalProviders?) .application([WORKER_APP_APPLICATION_COMMON, new Provider(MessageBus, useValue: bus),
.then((ref) => ref.bootstrap(MyApp)); new Provider(APP_INITIALIZER, useFactory: (zone, bus) => () => initAppThread(zone, bus), multi: true, deps: [NgZone, MessageBus])])
.bootstrap(MyApp);
} }
Future<dynamic> initAppThread(NgZone zone) { void initAppThread(NgZone zone) {
var bus = new MyAwesomeMessageBus(); /**
return genericWorkerAppProviders(myBus, zone); * Here you can do any initilization work that requires the app providers to be initialized.
* At a minimum, you must attach your bus to the zone and setup a DOM adapter.
* Depending on your environment you may choose to do more work here.
*/
} }
``` ```
Notice how we use the `WORKER_RENDER_APP_COMMON` providers instead of the `WORKER_RENDER_APP` providers on the render thread. Notice how we use the `WORKER_RENDER_APP_COMMON` providers instead of the `WORKER_RENDER_APP` providers on the render thread.
This is because the `WORKER_RENDER_APP` providers include an application initializer that starts a new WebWorker/Isolate. This is because the `WORKER_RENDER_APP` providers include an application initializer that starts a new WebWorker/Isolate.
The `WORKER_RENDER_APP_COMMON` providers make no assumption about where your application code lives. The `WORKER_RENDER_APP_COMMON` providers make no assumption about where your application code lives.
However, we now need to provide our own app initializer. At the very least this initializer needs to call `initializeGenericWorkerRenderer`. However, we now need to provide our own app initializer. At the very least this initializer needs to call `initializeGenericWorkerRenderer`.
This function performs necessary setup work to bootstrap the application.
Similarly we don&amp;t call `setupWebWorker` or `setupIsolate` from the application thread.
Instead we have our own initilization method that sets up our MessageBus and calls `genericWorkerAppProviders`
to finish setting up the application injector.
## MessageBroker ## MessageBroker
The MessageBroker is a higher level messaging abstraction that sits on top of the MessageBus. It is used when you The MessageBroker is a higher level messaging abstraction that sits on top of the MessageBus. It is used when you

View File

@ -0,0 +1,14 @@
library angular2.platform.worker_app;
export "package:angular2/src/platform/worker_app_common.dart"
show WORKER_APP_PLATFORM, WORKER_APP_APPLICATION_COMMON;
export "package:angular2/src/core/angular_entrypoint.dart"
show AngularEntrypoint;
export "package:angular2/src/platform/worker_app.dart"
show WORKER_APP_APPLICATION, RENDER_SEND_PORT;
export 'package:angular2/src/web_workers/shared/client_message_broker.dart'
show ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments;
export 'package:angular2/src/web_workers/shared/service_message_broker.dart'
show ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory;
export 'package:angular2/src/web_workers/shared/serializer.dart' show PRIMITIVE;
export 'package:angular2/src/web_workers/shared/message_bus.dart';

View File

@ -1,8 +1,8 @@
export { export {
WORKER_APP_PLATFORM, WORKER_APP_PLATFORM,
genericWorkerAppProviders WORKER_APP_APPLICATION_COMMON
} from 'angular2/src/platform/worker_app_common'; } from 'angular2/src/platform/worker_app_common';
export * from 'angular2/src/platform/worker_app'; export {WORKER_APP_APPLICATION} from 'angular2/src/platform/worker_app';
export { export {
ClientMessageBroker, ClientMessageBroker,
ClientMessageBrokerFactory, ClientMessageBrokerFactory,

View File

@ -3,19 +3,31 @@ library angular2.src.platform.worker_app;
import 'package:angular2/src/core/zone/ng_zone.dart'; import 'package:angular2/src/core/zone/ng_zone.dart';
import 'package:angular2/src/platform/server/webworker_adapter.dart'; import 'package:angular2/src/platform/server/webworker_adapter.dart';
import 'package:angular2/src/platform/worker_app_common.dart'; import 'package:angular2/src/platform/worker_app_common.dart';
import 'package:angular2/core.dart';
import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart'; import 'package:angular2/src/web_workers/shared/isolate_message_bus.dart';
import 'package:angular2/src/web_workers/shared/message_bus.dart';
import 'dart:isolate'; import 'dart:isolate';
setupIsolate(SendPort replyTo) { const OpaqueToken RENDER_SEND_PORT = const OpaqueToken("RenderSendPort");
return (NgZone zone) {
WebWorkerDomAdapter.makeCurrent();
const List<dynamic> WORKER_APP_APPLICATION = const [
WORKER_APP_APPLICATION_COMMON,
const Provider(MessageBus,
useFactory: createMessageBus, deps: const [NgZone, RENDER_SEND_PORT]),
const Provider(APP_INITIALIZER, useValue: setupIsolate, multi: true)
];
MessageBus createMessageBus(NgZone zone, SendPort replyTo) {
ReceivePort rPort = new ReceivePort(); ReceivePort rPort = new ReceivePort();
var sink = new WebWorkerMessageBusSink(replyTo, rPort); var sink = new WebWorkerMessageBusSink(replyTo, rPort);
var source = new IsolateMessageBusSource(rPort); var source = new IsolateMessageBusSource(rPort);
IsolateMessageBus bus = new IsolateMessageBus(sink, source); var bus = new IsolateMessageBus(sink, source);
return genericWorkerAppProviders(bus, zone); bus.attachToZone(zone);
}; return bus;
}
setupIsolate() {
WebWorkerDomAdapter.makeCurrent();
} }
class WebWorkerMessageBusSink extends IsolateMessageBusSink { class WebWorkerMessageBusSink extends IsolateMessageBusSink {

View File

@ -7,22 +7,31 @@ import {
PostMessageBusSink, PostMessageBusSink,
PostMessageBusSource PostMessageBusSource
} from 'angular2/src/web_workers/shared/post_message_bus'; } from 'angular2/src/web_workers/shared/post_message_bus';
import {genericWorkerAppProviders} from './worker_app_common'; import {WORKER_APP_APPLICATION_COMMON} from './worker_app_common';
import {APP_INITIALIZER} from 'angular2/core';
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
// TODO(jteplitz602) remove this and compile with lib.webworker.d.ts (#3492) // TODO(jteplitz602) remove this and compile with lib.webworker.d.ts (#3492)
interface PostMessageInterface { let _postMessage = {
(message: any, transferrables?:[ArrayBuffer]): void; postMessage: (message: any, transferrables?:[ArrayBuffer]) => {
(<any>postMessage)(message, transferrables);
} }
var _postMessage: PostMessageInterface = <any>postMessage; };
export function setupWebWorker(zone: NgZone): Promise<Array<Type | Provider | any[]>> { export const WORKER_APP_APPLICATION: Array<any /*Type | Provider | any[]*/> = [
WORKER_APP_APPLICATION_COMMON,
new Provider(MessageBus, {useFactory: createMessageBus, deps: [NgZone]}),
new Provider(APP_INITIALIZER, {useValue: setupWebWorker, multi: true})
];
function createMessageBus(zone: NgZone): MessageBus {
let sink = new PostMessageBusSink(_postMessage);
let source = new PostMessageBusSource();
let bus = new PostMessageBus(sink, source);
bus.attachToZone(zone);
return bus;
}
function setupWebWorker(): void {
Parse5DomAdapter.makeCurrent(); Parse5DomAdapter.makeCurrent();
var sink = new PostMessageBusSink({
postMessage:
(message: any, transferrables?:[ArrayBuffer]) => { _postMessage(message, transferrables); }
});
var source = new PostMessageBusSource();
var bus = new PostMessageBus(sink, source);
return genericWorkerAppProviders(bus, zone);
} }

View File

@ -1,9 +1,7 @@
import {XHR} from 'angular2/src/compiler/xhr'; import {XHR} from 'angular2/src/compiler/xhr';
import {WebWorkerXHRImpl} from 'angular2/src/web_workers/worker/xhr_impl'; import {WebWorkerXHRImpl} from 'angular2/src/web_workers/worker/xhr_impl';
import {ListWrapper} from 'angular2/src/facade/collection';
import {WebWorkerRenderer} from 'angular2/src/web_workers/worker/renderer'; import {WebWorkerRenderer} from 'angular2/src/web_workers/worker/renderer';
import {print, Type, CONST_EXPR, isPresent} from 'angular2/src/facade/lang'; import {print, Type, CONST_EXPR, isPresent} from 'angular2/src/facade/lang';
import {MessageBus} from 'angular2/src/web_workers/shared/message_bus';
import {Renderer} from 'angular2/src/core/render/api'; import {Renderer} from 'angular2/src/core/render/api';
import { import {
PLATFORM_DIRECTIVES, PLATFORM_DIRECTIVES,
@ -30,8 +28,6 @@ import {
RenderViewWithFragmentsStore RenderViewWithFragmentsStore
} from 'angular2/src/web_workers/shared/render_view_with_fragments_store'; } from 'angular2/src/web_workers/shared/render_view_with_fragments_store';
import {WebWorkerEventDispatcher} from 'angular2/src/web_workers/worker/event_dispatcher'; import {WebWorkerEventDispatcher} from 'angular2/src/web_workers/worker/event_dispatcher';
import {NgZone} from 'angular2/src/core/zone/ng_zone';
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
class PrintLogger { class PrintLogger {
log = print; log = print;
@ -43,7 +39,7 @@ class PrintLogger {
export const WORKER_APP_PLATFORM: Array<any /*Type | Provider | any[]*/> = export const WORKER_APP_PLATFORM: Array<any /*Type | Provider | any[]*/> =
CONST_EXPR([PLATFORM_COMMON_PROVIDERS]); CONST_EXPR([PLATFORM_COMMON_PROVIDERS]);
export const WORKER_APP_COMMON_PROVIDERS: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([ export const WORKER_APP_APPLICATION_COMMON: Array<any /*Type | Provider | any[]*/> = CONST_EXPR([
APPLICATION_COMMON_PROVIDERS, APPLICATION_COMMON_PROVIDERS,
COMPILER_PROVIDERS, COMPILER_PROVIDERS,
FORM_PROVIDERS, FORM_PROVIDERS,
@ -66,17 +62,3 @@ export const WORKER_APP_COMMON_PROVIDERS: Array<any /*Type | Provider | any[]*/>
function _exceptionHandler(): ExceptionHandler { function _exceptionHandler(): ExceptionHandler {
return new ExceptionHandler(new PrintLogger()); 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 {@link MessageBus} to the given {@link NgZone}.
*/
export function genericWorkerAppProviders(bus: MessageBus,
zone: NgZone): Promise<Array<Type | Provider | any[]>> {
bus.attachToZone(zone);
var bindings = ListWrapper.concat(WORKER_APP_COMMON_PROVIDERS, [
new Provider(MessageBus, {useValue: bus}),
]);
return PromiseWrapper.resolve(bindings);
}

View File

@ -9,15 +9,12 @@ import 'package:angular2/src/facade/lang.dart';
import 'package:angular2/src/facade/exceptions.dart'; import 'package:angular2/src/facade/exceptions.dart';
class GenericMessageBus implements MessageBus { class GenericMessageBus implements MessageBus {
final MessageBusSink _sink; MessageBusSink sink;
final MessageBusSource _source; MessageBusSource source;
MessageBusSink get sink => _sink;
MessageBusSource get source => _source;
GenericMessageBus(MessageBusSink sink, MessageBusSource source) GenericMessageBus(MessageBusSink sink, MessageBusSource source)
: _sink = sink, : sink = sink,
_source = source; source = source;
void attachToZone(NgZone zone) { void attachToZone(NgZone zone) {
sink.attachToZone(zone); sink.attachToZone(zone);

View File

@ -4,7 +4,7 @@ import 'package:angular2/src/platform/server/html_adapter.dart';
import "package:angular2/testing_internal.dart"; import "package:angular2/testing_internal.dart";
import "package:angular2/src/core/reflection/reflection_capabilities.dart"; import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart"; import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/platform/worker_app_common.dart" show WORKER_APP_COMMON_PROVIDERS; import "package:angular2/src/platform/worker_app_common.dart" show WORKER_APP_APPLICATION_COMMON;
import "package:angular2/platform/worker_app.dart" show WORKER_APP_PLATFORM; import "package:angular2/platform/worker_app.dart" show WORKER_APP_PLATFORM;
import "package:angular2/core.dart"; import "package:angular2/core.dart";
import "../shared/web_worker_test_util.dart"; import "../shared/web_worker_test_util.dart";
@ -19,7 +19,7 @@ main() {
reflector.reflectionCapabilities = new ReflectionCapabilities(); reflector.reflectionCapabilities = new ReflectionCapabilities();
var buses = createPairedMessageBuses(); var buses = createPairedMessageBuses();
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM])
.application([WORKER_APP_COMMON_PROVIDERS]); .application([WORKER_APP_APPLICATION_COMMON]);
}); });
}); });
} }

View File

@ -9,7 +9,7 @@ import "package:angular2/src/core/reflection/reflection.dart";
main(List<String> args, SendPort replyTo) { main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities(); reflector.reflectionCapabilities = new ReflectionCapabilities();
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM, new Provider(RENDER_SEND_PORT, useValue: replyTo)])
.asyncApplication(setupIsolate(replyTo)) .application([WORKER_APP_APPLICATION])
.then((ref) => ref.bootstrap(ImageDemo)); .bootstrap(ImageDemo);
} }

View File

@ -1,9 +1,7 @@
import {ImageDemo} from "./index_common"; import {ImageDemo} from "./index_common";
import {platform} from "angular2/core"; import {platform} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platform/worker_app"; import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app";
export function main() { export function main() {
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(ImageDemo)
.asyncApplication(setupWebWorker)
.then((ref) => ref.bootstrap(ImageDemo));
} }

View File

@ -9,7 +9,7 @@ import "package:angular2/src/core/reflection/reflection.dart";
main(List<String> args, SendPort replyTo) { main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities(); reflector.reflectionCapabilities = new ReflectionCapabilities();
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM, new Provider(RENDER_SEND_PORT, useValue: replyTo)])
.asyncApplication(setupIsolate(replyTo)) .application([WORKER_APP_APPLICATION])
.then((ref) => ref.bootstrap(HelloCmp)); .bootstrap(HelloCmp);
} }

View File

@ -1,9 +1,7 @@
import {HelloCmp} from "./index_common"; import {HelloCmp} from "./index_common";
import {platform} from "angular2/core"; import {platform} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platform/worker_app"; import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app";
export function main() { export function main() {
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(HelloCmp);
.asyncApplication(setupWebWorker)
.then((ref) => ref.bootstrap(HelloCmp));
} }

View File

@ -9,7 +9,7 @@ import "dart:isolate";
main(List<String> args, SendPort replyTo) { main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities(); reflector.reflectionCapabilities = new ReflectionCapabilities();
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM, new Provider(RENDER_SEND_PORT, useValue: replyTo)])
.asyncApplication(setupIsolate(replyTo)) .application([WORKER_APP_APPLICATION])
.then((ref) => ref.bootstrap(App)); .bootstrap(App);
} }

View File

@ -1,9 +1,7 @@
import {platform} from "angular2/core"; import {platform} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platform/worker_app"; import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app";
import {App} from "./index_common"; import {App} from "./index_common";
export function main() { export function main() {
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(App)
.asyncApplication(setupWebWorker)
.then((ref) => ref.bootstrap(App));
} }

View File

@ -9,7 +9,7 @@ import "package:angular2/src/core/reflection/reflection.dart";
main(List<String> args, SendPort replyTo) { main(List<String> args, SendPort replyTo) {
reflector.reflectionCapabilities = new ReflectionCapabilities(); reflector.reflectionCapabilities = new ReflectionCapabilities();
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM, new Provider(RENDER_SEND_PORT, useValue: replyTo)])
.asyncApplication(setupIsolate(replyTo)) .application([WORKER_APP_APPLICATION])
.then((ref) => ref.bootstrap(TodoApp)); .bootstrap(TodoApp);
} }

View File

@ -1,9 +1,7 @@
import {TodoApp} from "./index_common"; import {TodoApp} from "./index_common";
import {platform} from "angular2/core"; import {platform} from "angular2/core";
import {WORKER_APP_PLATFORM, setupWebWorker} from "angular2/platform/worker_app"; import {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION} from "angular2/platform/worker_app";
export function main() { export function main() {
platform([WORKER_APP_PLATFORM]) platform([WORKER_APP_PLATFORM]).application([WORKER_APP_APPLICATION]).bootstrap(TodoApp)
.asyncApplication(setupWebWorker)
.then((ref) => ref.bootstrap(TodoApp));
} }

View File

@ -5,24 +5,28 @@ import "package:angular2/src/web_workers/debug_tools/multi_client_server_message
import "package:angular2/platform/worker_app.dart"; import "package:angular2/platform/worker_app.dart";
import "package:angular2/core.dart"; import "package:angular2/core.dart";
import 'dart:io'; import 'dart:io';
import 'dart:async';
import "package:angular2/src/core/reflection/reflection_capabilities.dart"; import "package:angular2/src/core/reflection/reflection_capabilities.dart";
import "package:angular2/src/core/reflection/reflection.dart"; import "package:angular2/src/core/reflection/reflection.dart";
import "package:angular2/src/platform/server/html_adapter.dart"; import "package:angular2/src/platform/server/html_adapter.dart";
void main() { void main() {
reflector.reflectionCapabilities = new ReflectionCapabilities(); reflector.reflectionCapabilities = new ReflectionCapabilities();
platform([WORKER_APP_PLATFORM]) HttpServer.bind('127.0.0.1', 1337).then((HttpServer server) {
.asyncApplication(initAppThread)
.then((ref) => ref.bootstrap(TodoApp));
}
Future<dynamic> initAppThread(NgZone zone) {
Html5LibDomAdapter.makeCurrent();
return HttpServer.bind('127.0.0.1', 1337).then((HttpServer server) {
print("Server Listening for requests on 127.0.0.1:1337"); print("Server Listening for requests on 127.0.0.1:1337");
var bus = new MultiClientServerMessageBus.fromHttpServer(server); var bus = new MultiClientServerMessageBus.fromHttpServer(server);
return genericWorkerAppProviders(bus, zone);
platform([WORKER_APP_PLATFORM]).application([
WORKER_APP_APPLICATION_COMMON,
new Provider(MessageBus, useValue: bus),
new Provider(APP_INITIALIZER,
useFactory: initAppThread, multi: true, deps: [NgZone, MessageBus])
]).bootstrap(TodoApp);
}); });
} }
initAppThread(NgZone zone, MessageBus bus) {
return () {
Html5LibDomAdapter.makeCurrent();
bus.attachToZone(zone);
};
}