Skip to content

AF-1541 additional timing granularity #116

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions example/panel/modules/data_load_async_module.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ class DataLoadAsyncModule extends Module {

DataLoadAsyncActions _actions;
DataLoadAsyncComponents _components;
DataLoadAsyncStore _stores;
DataLoadAsyncEvents _events;
DataLoadAsyncStore _store;

DataLoadAsyncModule() {
_actions = new DataLoadAsyncActions();
_stores = new DataLoadAsyncStore(_actions);
_components = new DataLoadAsyncComponents(_actions, _stores);
_events = new DataLoadAsyncEvents();
_store = new DataLoadAsyncStore(_actions, _events);
_components = new DataLoadAsyncComponents(_actions, _store);
}

@override
Expand All @@ -42,8 +44,10 @@ class DataLoadAsyncModule extends Module {
@protected
Future<Null> onLoad() {
// trigger non-blocking async load of data
_events.didLoadData.first
.then((_) => specifyStartupTiming(StartupTimingSpecifier.firstUseful));
_actions.loadData();
return new Future.value();
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could introduce an issue if a consumer treats the returned Future directly.

// This will throw.
_module.onLoad().then((_) => ...);

Copy link
Contributor Author

@toddbeckman-wf toddbeckman-wf Jul 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was just toying around with the examples and forgot to put it back. I'll probably do that before pushing for the reviews on this.

}
}

Expand All @@ -62,15 +66,20 @@ class DataLoadAsyncActions {
final Action loadData = new Action();
}

DispatchKey _dispatchKey = new DispatchKey('DataLoadAsync');

class DataLoadAsyncEvents {
final Event didLoadData = new Event(_dispatchKey);
}

class DataLoadAsyncStore extends Store {
DataLoadAsyncActions _actions;
List<String> _data;
bool _isLoading;
DataLoadAsyncEvents _events;
List<String> _data = [];
bool _isLoading = false;

DataLoadAsyncStore(this._actions) {
_isLoading = false;
_data = [];
triggerOnAction(_actions.loadData, _loadData);
DataLoadAsyncStore(this._actions, this._events) {
manageActionSubscription(_actions.loadData.listen(_loadData));
}

/// Public data
Expand All @@ -89,6 +98,8 @@ class DataLoadAsyncStore extends Store {
// trigger on return of final data
_data = ['Aaron', 'Dustin', 'Evan', 'Jay', 'Max', 'Trent'];
_isLoading = false;
_events.didLoadData(null, _dispatchKey);
trigger();
}
}

Expand Down
162 changes: 162 additions & 0 deletions example/panel/modules/sample_tracer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import 'dart:async';
import 'package:opentracing/opentracing.dart';

class SampleSpan implements Span {
static int _nextId = 0;
final int _id = _nextId++;

@override
final List<Reference> references;

@override
final Map<String, dynamic> tags;

@override
final List<LogData> logData = [];

@override
final String operationName;

@override
SpanContext context;

@override
final DateTime startTime;
DateTime _endTime;

Completer<Span> _whenFinished = new Completer<Span>();

SampleSpan(
this.operationName, {
SpanContext childOf,
this.references,
DateTime startTime,
Map<String, dynamic> tags,
})
: this.startTime = startTime ?? new DateTime.now(),
this.tags = tags ?? {} {
if (childOf != null) {
references.add(new Reference.childOf(childOf));
}
setTag('span.kind', 'client');

final parent = parentContext;
if (parent != null) {
this.context = new SpanContext(spanId: _id, traceId: parent.traceId);
this.context.baggage.addAll(parent.baggage);
} else {
this.context = new SpanContext(spanId: _id, traceId: _id);
}
}

@override
void addTags(Map<String, dynamic> newTags) => tags.addAll(newTags);

@override
Duration get duration => _endTime?.difference(startTime);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❓Are consumers of Span aware that this may be null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figure it's not important here because it's just in the examples.


@override
DateTime get endTime => _endTime;

@override
void finish({DateTime finishTime}) {
if (_whenFinished == null) {
return;
}

_endTime = finishTime ?? new DateTime.now();
_whenFinished.complete(this);
_whenFinished = null;
}

@override
void log(String event, {dynamic payload, DateTime timestamp}) =>
logData.add(new LogData(timestamp ?? new DateTime.now(), event, payload));

@override
SpanContext get parentContext =>
references.isEmpty ? null : references.first.referencedContext;

@override
void setTag(String tagName, dynamic value) => tags[tagName] = value;

@override
Future<Span> get whenFinished => _whenFinished.future;

@override
String toString() {
final sb = new StringBuffer('SampleSpan(');
sb
..writeln('traceId: ${context.traceId}')
..writeln('spanId: ${context.spanId}')
..writeln('operationName: $operationName')
..writeln('tags: ${tags.toString()}')
..writeln('startTime: ${startTime.toString()}');

if (_endTime != null) {
sb
..writeln('endTime: ${endTime.toString()}')
..writeln('duration: ${duration.toString()}');
}

if (logData.isNotEmpty) {
sb.writeln('logData: ${logData.toString()}');
}

if (references.isNotEmpty) {
final reference = references.first;
sb.writeln(
'reference: ${reference.referenceType} ${reference.referencedContext.spanId}');
}

sb.writeln(')');

return sb.toString();
}
}

class SampleTracer implements AbstractTracer {
@override
SampleSpan startSpan(
String operationName, {
SpanContext childOf,
List<Reference> references,
DateTime startTime,
Map<String, dynamic> tags,
}) {
return new SampleSpan(
operationName,
childOf: childOf,
references: references,
startTime: startTime,
tags: tags,
)
..whenFinished.then((span) {
print(span.toString());
});
}

@override
Reference childOf(SpanContext context) => new Reference.childOf(context);

@override
Reference followsFrom(SpanContext context) =>
new Reference.followsFrom(context);

@override
SpanContext extract(String format, dynamic carrier) {
throw new UnimplementedError(
'Sample tracer for example purposes does not support advanced tracing behavior.');
}

@override
void inject(SpanContext spanContext, String format, dynamic carrier) {
throw new UnimplementedError(
'Sample tracer for example purposes does not support advanced tracing behavior.');
}

@override
Future<dynamic> flush() {
return null;
}
}
6 changes: 6 additions & 0 deletions example/panel/panel_app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,19 @@ import 'package:platform_detect/platform_detect.dart';
import 'package:react/react_dom.dart' as react_dom;
import 'package:react/react_client.dart' as react_client;
import 'package:w_module/w_module.dart' hide Event;
import 'package:opentracing/opentracing.dart';

import 'modules/panel_module.dart';
import 'modules/sample_tracer.dart';

Future<Null> main() async {
Element container = querySelector('#panel-container');
react_client.setClientConfiguration();

final tracer = new SampleTracer();
initGlobalTracer(tracer);
assert(globalTracer() == tracer);

// instantiate the core app module and wait for it to complete loading
PanelModule panelModule = new PanelModule();
await panelModule.load();
Expand Down
Loading