OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library appengine; | 5 library appengine; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:io'; | 8 import 'dart:io'; |
9 | 9 |
| 10 export 'package:gcloud/http.dart'; |
10 import 'package:gcloud/service_scope.dart' as ss; | 11 import 'package:gcloud/service_scope.dart' as ss; |
11 | 12 |
12 import 'src/appengine_internal.dart' as appengine_internal; | 13 import 'src/appengine_internal.dart' as appengine_internal; |
13 import 'src/app_engine_request_handler.dart'; | 14 import 'src/app_engine_request_handler.dart'; |
14 import 'src/client_context.dart'; | 15 import 'src/client_context.dart'; |
15 | 16 |
16 export 'package:gcloud/http.dart'; | |
17 export 'api/errors.dart'; | 17 export 'api/errors.dart'; |
18 export 'api/logging.dart'; | 18 export 'api/logging.dart'; |
19 export 'api/modules.dart'; | 19 export 'api/modules.dart'; |
20 export 'api/memcache.dart'; | 20 export 'api/memcache.dart'; |
21 export 'api/remote_api.dart'; | 21 export 'api/remote_api.dart'; |
22 export 'api/users.dart'; | 22 export 'api/users.dart'; |
23 export 'src/app_engine_request_handler.dart'; | 23 export 'src/app_engine_request_handler.dart'; |
24 export 'src/client_context.dart'; | 24 export 'src/client_context.dart'; |
25 | 25 |
26 const Symbol _APPENGINE_CONTEXT = #appengine.context; | 26 const Symbol _APPENGINE_CONTEXT = #appengine.context; |
27 | 27 |
28 /** | 28 /** |
29 * Starts serving requests coming to this AppEngine application. | 29 * Starts serving requests coming to this AppEngine application. |
30 * | 30 * |
31 * This function will start an HTTP server and will forward new HTTP requests | 31 * This function will start an HTTP server and will forward new HTTP requests |
32 * to [handler]. | 32 * to [handler]. |
33 * | 33 * |
34 * The [handler] will be executed inside a new request handler zone for every | 34 * The [handler] will be executed inside a new request handler zone for every |
35 * new request. This will isolate different requests from each other. | 35 * new request. This will isolate different requests from each other. |
36 * Each [handler] has access to a [ClientContext] using the [context] getter | 36 * Each [handler] has access to a [ClientContext] using the [context] getter |
37 * in this library. It can be used to access appengine services, e.g. memcache. | 37 * in this library. It can be used to access appengine services, e.g. memcache. |
38 * | 38 * |
39 * In case an uncaught error occurs inside the request handler, the request | 39 * In case an uncaught error occurs inside the request handler, the request |
40 * will be closed with an "500 Internal Server Error", if possible, and the | 40 * will be closed with an "500 Internal Server Error", if possible, and the |
41 * given [onError] handler will be called. | 41 * given [onError] handler will be called. |
42 * | 42 * |
43 * The [onError] function can take either the error object, or the error object | 43 * The [onError] function can take either the error object, or the error object |
44 * and a stack as an argument. If [onError] was not provided, errors will get | 44 * and a stack as an argument. If [onError] was not provided, errors will get |
45 * printed out to the stdout of this process. | 45 * printed out to the stdout of this process. |
| 46 * |
| 47 * The returned `Future` will complete when the HTTP server has been shutdown |
| 48 * and is no longer serving requests. |
46 */ | 49 */ |
47 Future runAppEngine(AppEngineRequestHandler handler, {Function onError}) { | 50 Future runAppEngine(AppEngineRequestHandler handler, {Function onError}) { |
48 var errorHandler; | 51 var errorHandler; |
49 if (onError != null) { | 52 if (onError != null) { |
50 if (onError is ZoneUnaryCallback) { | 53 if (onError is ZoneUnaryCallback) { |
51 errorHandler = (error, stack) => onError(error); | 54 errorHandler = (error, stack) => onError(error); |
52 } else if (onError is ZoneBinaryCallback) { | 55 } else if (onError is ZoneBinaryCallback) { |
53 errorHandler = onError; | 56 errorHandler = onError; |
54 } else { | 57 } else { |
55 throw new ArgumentError( | 58 throw new ArgumentError( |
56 'The [onError] argument must take either one or two arguments.'); | 59 'The [onError] argument must take either one or two arguments.'); |
57 } | 60 } |
58 } else { | 61 } else { |
59 errorHandler = (error, stack) { | 62 errorHandler = (error, stack) { |
60 print("$error\nStack:\n$stack"); | 63 print("$error\nStack:\n$stack"); |
61 }; | 64 }; |
62 } | 65 } |
63 | 66 |
64 return appengine_internal.runAppEngine((HttpRequest request, | 67 return appengine_internal.runAppEngine((HttpRequest request, |
65 ClientContext context) { | 68 ClientContext context) { |
66 ss.register(_APPENGINE_CONTEXT, context); | 69 ss.register(_APPENGINE_CONTEXT, context); |
67 handler(request); | 70 handler(request); |
68 }, errorHandler); | 71 }, errorHandler); |
69 } | 72 } |
70 | 73 |
71 /** | 74 /** |
| 75 * Runs [callback] inside a new service scope with appengine services added. |
| 76 * |
| 77 * The services available to `callback` are all non-request specific appengine |
| 78 * services e.g. `memcacheService`, `dbService`. |
| 79 * |
| 80 * See `package:gcloud/service_scope.dart` for more information on service |
| 81 * scopes. |
| 82 * |
| 83 * Here is an example on how this can be used: |
| 84 * |
| 85 * import 'dart:async'; |
| 86 * import 'dart:io'; |
| 87 * import 'package:appengine/appengine.dart'; |
| 88 * |
| 89 * Future backgroundWork() { |
| 90 * return dbService.query(Person).run().toList().then((persons) { |
| 91 * // Do something with `persons`. |
| 92 * }); |
| 93 * } |
| 94 * |
| 95 * void mainHandler(HttpRequest request) { |
| 96 * dbService.query(Greeting).run().toList().then((greetings) { |
| 97 * request.response |
| 98 * ..write('Number of greetings: ${greetings.length}') |
| 99 * ..close(); |
| 100 * }); |
| 101 * } |
| 102 * |
| 103 * main() { |
| 104 * withAppEngineServices(() { |
| 105 * return Future.wait([ |
| 106 * runAppEngine(mainHandler), |
| 107 * backgroundWork(), |
| 108 * ]); |
| 109 * }); |
| 110 * } |
| 111 */ |
| 112 Future withAppEngineServices(Future callback()) { |
| 113 return appengine_internal.withAppEngineServices(callback); |
| 114 } |
| 115 |
| 116 /** |
72 * Returns the [ClientContext] of the current request. | 117 * Returns the [ClientContext] of the current request. |
73 * | 118 * |
74 * This getter can only be called inside a request handler which was passed to | 119 * This getter can only be called inside a request handler which was passed to |
75 * [runAppEngine]. | 120 * [runAppEngine]. |
76 */ | 121 */ |
77 ClientContext get context => ss.lookup(_APPENGINE_CONTEXT); | 122 ClientContext get context => ss.lookup(_APPENGINE_CONTEXT); |
OLD | NEW |