Remove ResponseContext.dispose

This commit is contained in:
Tobe O 2018-08-20 21:45:33 -04:00
parent 582227f99e
commit 15e5cef691
5 changed files with 34 additions and 43 deletions

View file

@ -56,4 +56,7 @@ not very elegant.
* `AngelHttp.useZone` now defaults to `false`.
* `ResponseContext` now starts in streaming mode by default; the response buffer is opt-in,
as in many cases it is unnecessary and slows down response time.
* `ResponseContext.streaming` was replaced by `ResponseContext.isBuffered`.
* `ResponseContext.streaming` was replaced by `ResponseContext.isBuffered`.
* Made `LockableBytesBuilder` public.
* Removed the now-obsolete `ResponseContext.willCloseItself`.
* Removed `ResponseContext.dispose`.

View file

@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';

View file

@ -20,7 +20,6 @@ final RegExp _straySlashes = new RegExp(r'(^/+)|(/+$)');
abstract class ResponseContext<RawResponse>
implements StreamSink<List<int>>, StringSink {
final Map properties = {};
BytesBuilder _buffer;
final Map<String, String> _headers = {'server': 'angel'};
Completer _done;
@ -87,7 +86,7 @@ abstract class ResponseContext<RawResponse>
bool get isBuffered;
/// A set of UTF-8 encoded bytes that will be written to the response.
BytesBuilder get buffer => _buffer;
BytesBuilder get buffer;
/// The underlying [RawResponse] under this instance.
RawResponse get rawResponse;
@ -95,11 +94,6 @@ abstract class ResponseContext<RawResponse>
/// Gets or sets the content type to send back to a client.
MediaType contentType = new MediaType('text', 'plain');
/// Set this to true if you will manually close the response.
///
/// If `true`, all response finalizers will be skipped.
bool willCloseItself = false;
static StateError closed() =>
new StateError('Cannot modify a closed response.');
@ -124,26 +118,14 @@ abstract class ResponseContext<RawResponse>
///
/// This method should be overwritten, setting [streaming] to `false`, **after** a `super` call.
Future close() {
if (_buffer is LockableBytesBuilder) {
(_buffer as LockableBytesBuilder).lock();
if (buffer is LockableBytesBuilder) {
(buffer as LockableBytesBuilder).lock();
}
if (_done?.isCompleted == false) _done.complete();
return new Future.value();
}
/// Disposes of all resources.
void dispose() {
close();
properties.clear();
encoders.clear();
_buffer.clear();
cookies.clear();
app = null;
_headers.clear();
serializer = null;
}
/// Prevents further request handlers from running on the response, except for response finalizers.
///
/// To disable response finalizers, see [willCloseItself].

View file

@ -180,7 +180,7 @@ class AngelHttp {
var e = ee as AngelHttpException;
return handleAngelHttpException(
e, e.stackTrace ?? st, req, res, request);
}).whenComplete(() => res.dispose());
});
} else {
var zoneSpec = new ZoneSpecification(
print: (self, parent, zone, line) {
@ -239,9 +239,7 @@ class AngelHttp {
// so use a try/catch, and recover when need be.
try {
return zone.run(handle).whenComplete(() {
res.dispose();
});
return zone.run(handle);
} catch (e, st) {
zone.handleUncaughtError(e, st);
return Future.value();
@ -287,7 +285,7 @@ class AngelHttp {
Future sendResponse(
HttpRequest request, RequestContext req, ResponseContext res,
{bool ignoreFinalizers: false}) {
if (res.willCloseItself) return new Future.value();
if (!res.isBuffered) return new Future.value();
Future finalizers = ignoreFinalizers == true
? new Future.value()

View file

@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import '../core/core.dart';
import 'http_request_context.dart';
@ -10,8 +11,10 @@ class HttpResponseContext extends ResponseContext<HttpResponse> {
final HttpResponse rawResponse;
Angel app;
LockableBytesBuilder _buffer;
final HttpRequestContext _correspondingRequest;
bool _isClosed = false, _useStream = true;
bool _isClosed = false, _streamInitialized = false;
HttpResponseContext(this.rawResponse, this.app, [this._correspondingRequest]);
@ -26,9 +29,10 @@ class HttpResponseContext extends ResponseContext<HttpResponse> {
}
@override
bool get streaming {
return _useStream;
}
bool get isBuffered => _buffer != null;
@override
BytesBuilder get buffer => _buffer;
@override
void addError(Object error, [StackTrace stackTrace]) {
@ -37,17 +41,21 @@ class HttpResponseContext extends ResponseContext<HttpResponse> {
}
@override
bool useStream() {
if (!_useStream) {
void enableBuffer() {
_buffer = new LockableBytesBuilder();
}
bool _openStream() {
if (!_streamInitialized) {
// If this is the first stream added to this response,
// then add headers, status code, etc.
rawResponse
..statusCode = statusCode
..cookies.addAll(cookies);
headers.forEach(rawResponse.headers.set);
willCloseItself = _useStream = _isClosed = true;
_isClosed = true;
releaseCorrespondingRequest();
return true;
return _streamInitialized = true;
}
return false;
@ -55,14 +63,15 @@ class HttpResponseContext extends ResponseContext<HttpResponse> {
@override
void end() {
_buffer?.lock();
_isClosed = true;
super.end();
}
@override
Future addStream(Stream<List<int>> stream) {
if (_isClosed && !_useStream) throw ResponseContext.closed();
var firstStream = useStream();
if (_isClosed && isBuffered) throw ResponseContext.closed();
var firstStream = _openStream();
Stream<List<int>> output = stream;
@ -107,17 +116,18 @@ class HttpResponseContext extends ResponseContext<HttpResponse> {
@override
void add(List<int> data) {
if (_isClosed && !_useStream)
if (_isClosed && isBuffered)
throw ResponseContext.closed();
else if (_useStream)
else if (!isBuffered) {
_openStream();
rawResponse.add(data);
else
} else
buffer.add(data);
}
@override
Future close() {
if (_useStream) {
if (!isBuffered) {
try {
rawResponse.close();
} catch (_) {
@ -128,7 +138,6 @@ class HttpResponseContext extends ResponseContext<HttpResponse> {
_isClosed = true;
super.close();
_useStream = false;
return new Future.value();
}
}