Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
e3e18921
Unverified
Commit
e3e18921
authored
Apr 06, 2020
by
Mouad Debbar
Committed by
GitHub
Apr 06, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[web] Fix race condition in widget benchmarks (#53952)
parent
de27d713
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
63 additions
and
44 deletions
+63
-44
recorder.dart
dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
+63
-44
No files found.
dev/benchmarks/macrobenchmarks/lib/src/web/recorder.dart
View file @
e3e18921
...
...
@@ -305,8 +305,7 @@ abstract class SceneBuilderRecorder extends Recorder {
/// }
/// }
/// ```
abstract
class
WidgetRecorder
extends
Recorder
implements
RecordingWidgetsBindingListener
{
abstract
class
WidgetRecorder
extends
Recorder
implements
FrameRecorder
{
WidgetRecorder
({
@required
String
name
})
:
super
.
_
(
name
);
/// Creates a widget to be benchmarked.
...
...
@@ -318,9 +317,10 @@ abstract class WidgetRecorder extends Recorder
Widget
createWidget
();
@override
Profile
profile
;
VoidCallback
didStop
;
final
Completer
<
Profile
>
_profileCompleter
=
Completer
<
Profile
>();
Profile
profile
;
Completer
<
void
>
_runCompleter
;
Stopwatch
_drawFrameStopwatch
;
...
...
@@ -340,27 +340,32 @@ abstract class WidgetRecorder extends Recorder
if
(
profile
.
shouldContinue
())
{
window
.
scheduleFrame
();
}
else
{
_profileCompleter
.
complete
(
profile
);
didStop
();
_runCompleter
.
complete
();
}
}
@override
void
_onError
(
dynamic
error
,
StackTrace
stackTrace
)
{
_
profile
Completer
.
completeError
(
error
,
stackTrace
);
_
run
Completer
.
completeError
(
error
,
stackTrace
);
}
@override
Future
<
Profile
>
run
()
{
profile
=
Profile
(
name:
name
);
Future
<
Profile
>
run
()
async
{
_runCompleter
=
Completer
<
void
>();
final
Profile
localProfile
=
profile
=
Profile
(
name:
name
);
final
_RecordingWidgetsBinding
binding
=
_RecordingWidgetsBinding
.
ensureInitialized
();
final
Widget
widget
=
createWidget
();
binding
.
_beginRecording
(
this
,
widget
);
_profileCompleter
.
future
.
whenComplete
(()
{
try
{
await
_runCompleter
.
future
;
return
localProfile
;
}
finally
{
_runCompleter
=
null
;
profile
=
null
;
});
return
_profileCompleter
.
future
;
}
}
}
...
...
@@ -371,8 +376,7 @@ abstract class WidgetRecorder extends Recorder
/// another frame that clears the screen. It repeats this process, measuring the
/// performance of frames that render the widget and ignoring the frames that
/// clear the screen.
abstract
class
WidgetBuildRecorder
extends
Recorder
implements
RecordingWidgetsBindingListener
{
abstract
class
WidgetBuildRecorder
extends
Recorder
implements
FrameRecorder
{
WidgetBuildRecorder
({
@required
String
name
})
:
super
.
_
(
name
);
/// Creates a widget to be benchmarked.
...
...
@@ -383,9 +387,10 @@ abstract class WidgetBuildRecorder extends Recorder
Widget
createWidget
();
@override
Profile
profile
;
VoidCallback
didStop
;
final
Completer
<
Profile
>
_profileCompleter
=
Completer
<
Profile
>();
Profile
profile
;
Completer
<
void
>
_runCompleter
;
Stopwatch
_drawFrameStopwatch
;
...
...
@@ -427,26 +432,31 @@ abstract class WidgetBuildRecorder extends Recorder
showWidget
=
!
showWidget
;
_hostState
.
_setStateTrampoline
();
}
else
{
_profileCompleter
.
complete
(
profile
);
didStop
();
_runCompleter
.
complete
();
}
}
@override
void
_onError
(
dynamic
error
,
StackTrace
stackTrace
)
{
_
profile
Completer
.
completeError
(
error
,
stackTrace
);
_
run
Completer
.
completeError
(
error
,
stackTrace
);
}
@override
Future
<
Profile
>
run
()
{
profile
=
Profile
(
name:
name
);
Future
<
Profile
>
run
()
async
{
_runCompleter
=
Completer
<
void
>();
final
Profile
localProfile
=
profile
=
Profile
(
name:
name
);
final
_RecordingWidgetsBinding
binding
=
_RecordingWidgetsBinding
.
ensureInitialized
();
binding
.
_beginRecording
(
this
,
_WidgetBuildRecorderHost
(
this
));
_profileCompleter
.
future
.
whenComplete
(()
{
try
{
await
_runCompleter
.
future
;
return
localProfile
;
}
finally
{
_runCompleter
=
null
;
profile
=
null
;
});
return
_profileCompleter
.
future
;
}
}
}
...
...
@@ -698,9 +708,10 @@ String _ratioToPercent(double value) {
/// Implemented by recorders that use [_RecordingWidgetsBinding] to receive
/// frame life-cycle calls.
abstract
class
RecordingWidgetsBindingListener
{
/// The profile where the benchmark is collecting metrics.
Profile
profile
;
abstract
class
FrameRecorder
{
/// Called by the recorder when it stops recording and doesn't need to collect
/// any more data.
set
didStop
(
VoidCallback
cb
);
/// Called just before calling [SchedulerBinding.handleDrawFrame].
void
frameWillDraw
();
...
...
@@ -739,19 +750,31 @@ class _RecordingWidgetsBinding extends BindingBase
return
WidgetsBinding
.
instance
as
_RecordingWidgetsBinding
;
}
RecordingWidgetsBindingListener
_listen
er
;
FrameRecorder
_record
er
;
bool
_hasErrored
=
false
;
void
_beginRecording
(
RecordingWidgetsBindingListener
recorder
,
Widget
widget
)
{
/// To short-circuit all frame lifecycle methods when the benchmark has
/// stopped collecting data.
bool
_benchmarkStopped
=
false
;
void
_beginRecording
(
FrameRecorder
recorder
,
Widget
widget
)
{
if
(
_recorder
!=
null
)
{
throw
Exception
(
'Cannot call _RecordingWidgetsBinding._beginRecording more than once'
,
);
}
final
FlutterExceptionHandler
originalOnError
=
FlutterError
.
onError
;
recorder
.
didStop
=
()
{
_benchmarkStopped
=
true
;
};
// Fail hard and fast on errors. Benchmarks should not have any errors.
FlutterError
.
onError
=
(
FlutterErrorDetails
details
)
{
_haltBenchmarkWithError
(
details
.
exception
,
details
.
stack
);
originalOnError
(
details
);
};
_
listen
er
=
recorder
;
_
record
er
=
recorder
;
runApp
(
widget
);
}
...
...
@@ -759,22 +782,17 @@ class _RecordingWidgetsBinding extends BindingBase
if
(
_hasErrored
)
{
return
;
}
_
listen
er
.
_onError
(
error
,
stackTrace
);
_
record
er
.
_onError
(
error
,
stackTrace
);
_hasErrored
=
true
;
}
/// To avoid calling [Profile.shouldContinue] every time [scheduleFrame] is
/// called, we cache this value at the beginning of the frame.
bool
_benchmarkStopped
=
false
;
@override
void
handleBeginFrame
(
Duration
rawTimeStamp
)
{
// Don't keep on truckin' if there's an error.
if
(
_hasErrored
)
{
// Don't keep on truckin' if there's an error
or the benchmark has stopped
.
if
(
_hasErrored
||
_benchmarkStopped
)
{
return
;
}
try
{
_benchmarkStopped
=
!
_listener
.
profile
.
shouldContinue
();
super
.
handleBeginFrame
(
rawTimeStamp
);
}
catch
(
error
,
stackTrace
)
{
_haltBenchmarkWithError
(
error
,
stackTrace
);
...
...
@@ -784,22 +802,23 @@ class _RecordingWidgetsBinding extends BindingBase
@override
void
scheduleFrame
()
{
// Don't keep on truckin' if there's an error.
if
(
!
_benchmarkStopped
&&
!
_hasError
ed
)
{
super
.
scheduleFrame
()
;
// Don't keep on truckin' if there's an error
or the benchmark has stopped
.
if
(
_hasErrored
||
_benchmarkStopp
ed
)
{
return
;
}
super
.
scheduleFrame
();
}
@override
void
handleDrawFrame
()
{
// Don't keep on truckin' if there's an error.
if
(
_hasErrored
)
{
// Don't keep on truckin' if there's an error
or the benchmark has stopped
.
if
(
_hasErrored
||
_benchmarkStopped
)
{
return
;
}
try
{
_
listen
er
.
frameWillDraw
();
_
record
er
.
frameWillDraw
();
super
.
handleDrawFrame
();
_
listen
er
.
frameDidDraw
();
_
record
er
.
frameDidDraw
();
}
catch
(
error
,
stackTrace
)
{
_haltBenchmarkWithError
(
error
,
stackTrace
);
rethrow
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment