Skip to content

Commit 52cfb71

Browse files
author
dustinhuynh
committed
Refine the doubling logic in sample set #418
1 parent 88b78dd commit 52cfb71

File tree

8 files changed

+137
-160
lines changed

8 files changed

+137
-160
lines changed

classes/cron_processor.php

Lines changed: 13 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,18 @@
2828
* @copyright 2022, Catalyst IT
2929
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
3030
*/
31-
class cron_processor implements processor {
31+
class cron_processor extends processor {
3232
/** @var float Timestamp updated after processing each sample */
3333
public $sampletime;
3434

35-
/** @var sample_set A sample set recorded while processing a task */
36-
public $tasksampleset = null;
37-
38-
/** @var sample_set A sample set for memory usage recorded while processing a task */
39-
protected $memoryusagesampleset;
40-
41-
/** @var int */
42-
protected $samplingperiod;
43-
44-
/** @var int */
45-
protected $samplelimit;
46-
47-
/** @var int */
48-
protected $maxsamples;
49-
50-
/** @var int */
51-
protected $logcount = 0;
52-
53-
/** @var bool */
54-
protected static $alreadyprofiling = false;
55-
56-
/** @var array */
57-
protected static $logs = [];
35+
/**
36+
* Construct the web processor.
37+
*/
38+
public function __construct() {
39+
// Preload config values to avoid DB access during processing. See manager::get_altconnection() for more information.
40+
parent::__construct();
41+
$this->minduration = (float) get_config('tool_excimer', 'task_min_duration');
42+
}
5843

5944
/**
6045
* Initialises the processor
@@ -64,10 +49,7 @@ class cron_processor implements processor {
6449
public function init(manager $manager) {
6550
$this->sampletime = $manager->get_starttime();
6651

67-
// Preload config values to avoid DB access during processing. See manager::get_altconnection() for more information.
68-
$this->samplingperiod = script_metadata::get_sampling_period();
69-
$this->samplelimit = script_metadata::get_sample_limit();
70-
$this->maxsamples = script_metadata::get_max_samples();
52+
// The callback is triggered when the number of samples reach the maxsamples and when profiler is destroyed.
7153
$manager->get_profiler()->setFlushCallback(function ($log) use ($manager) {
7254
$this->on_interval($log, $manager);
7355
}, $this->maxsamples);
@@ -84,7 +66,7 @@ function () use ($manager) {
8466

8567
/**
8668
* Get sampling period of processor
87-
*
69+
* (used for testing)
8870
* @return int sampling period
8971
*/
9072
public function get_sampling_period() {
@@ -93,35 +75,13 @@ public function get_sampling_period() {
9375

9476
/**
9577
* Get sample limit of processor
96-
*
78+
* (used for testing)
9779
* @return int sample_limit
9880
*/
9981
public function get_sample_limit() {
10082
return $this->samplelimit;
10183
}
10284

103-
/**
104-
* Gets the minimum duration required for a profile to be saved, as seconds.
105-
*
106-
* @return float
107-
* @throws \dml_exception
108-
*/
109-
public function get_min_duration(): float {
110-
return (float) get_config('tool_excimer', 'task_min_duration');
111-
}
112-
113-
/**
114-
* Doubling the sampling period when we reach the samples limit
115-
*
116-
* @param manager $manager
117-
*/
118-
public function on_reach_limit(manager $manager) {
119-
$this->samplingperiod *= 2;
120-
// This will take effect the next time start() is called.
121-
$manager->get_profiler()->setPeriod($this->samplingperiod);
122-
$manager->get_profiler()->start();
123-
}
124-
12585
/**
12686
* Examines a sample generated by the profiler.
12787
*
@@ -246,7 +206,7 @@ public function process(manager $manager, float $finishtime): profile {
246206
$profile->set('flamedatad3', flamed3_node::from_sample_set_samples($this->tasksampleset->samples));
247207
$profile->set('numsamples', count($this->tasksampleset->samples));
248208
$profile->set('numevents', $this->tasksampleset->count());
249-
$profile->set('samplerate', $this->samplingperiod * 1000);
209+
$profile->set('samplerate', (int) (($duration * 1000) / $this->tasksampleset->count()));
250210
$profile->save_record();
251211
}
252212
return $profile;

classes/manager.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,6 @@ public function __construct(processor $processor) {
165165
*/
166166
public function init() {
167167
if (!self::is_testing()) {
168-
script_metadata::init();
169-
profile_helper::init();
170-
171168
$sampleperiod = script_metadata::get_sampling_period();
172169
$this->profiler = new \ExcimerProfiler();
173170
$this->profiler->setPeriod($sampleperiod);
@@ -193,6 +190,8 @@ public function start_processor() {
193190
*
194191
*/
195192
public static function create() {
193+
script_metadata::init();
194+
profile_helper::init();
196195
if (self::is_cron()) {
197196
self::$instance = new manager(new cron_processor());
198197
} else {

classes/processor.php

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,62 @@
3333
*
3434
* @package tool_excimer
3535
*/
36-
interface processor {
36+
class processor {
37+
/** @var int */
38+
protected $minduration;
39+
40+
/** @var sample_set */
41+
public $tasksampleset;
42+
43+
/** @var sample_set */
44+
public $memoryusagesampleset;
45+
46+
/** @var int */
47+
protected $samplingperiod;
48+
49+
/** @var int */
50+
protected $samplelimit;
51+
52+
/** @var int */
53+
protected $maxsamples;
54+
55+
/** @var int */
56+
protected $logcount = 0;
57+
58+
/** @var bool */
59+
protected static $alreadyprofiling = false;
60+
61+
/** @var array */
62+
protected static $logs = [];
63+
64+
/**
65+
* Construct the processor.
66+
*/
67+
public function __construct() {
68+
// Preload config values to avoid DB access during processing. See manager::get_altconnection() for more information.
69+
$this->samplingperiod = script_metadata::get_sampling_period();
70+
$this->samplelimit = script_metadata::get_sample_limit();
71+
$this->maxsamples = script_metadata::get_max_samples();
72+
}
73+
3774
/**
38-
* Initialises the processor
75+
* Doubling the sampling period when we reach the samples limit
3976
*
40-
* @param manager $manager The profiler manager object
77+
* @param manager $manager
4178
*/
42-
public function init(manager $manager);
79+
public function on_reach_limit(manager $manager) {
80+
$this->samplingperiod *= 2;
81+
// This will take effect the next time start() is called.
82+
$manager->get_profiler()->setPeriod($this->samplingperiod);
83+
$manager->get_profiler()->start();
84+
}
4385

4486
/**
4587
* Gets the minimum duration required for a profile to be saved, as seconds.
4688
*
4789
* @return float
4890
*/
49-
public function get_min_duration(): float;
91+
public function get_min_duration(): float {
92+
return $this->minduration;
93+
}
5094
}

classes/profile.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ public function download(): void {
194194
*
195195
* @param string $json
196196
* @return bool|int the id of the imported profile, or false if unsuccessful
197+
* @throws \coding_exception
197198
*/
198199
public static function import(string $json) {
199200
global $DB;
@@ -225,7 +226,9 @@ public static function import(string $json) {
225226

226227
foreach ($data as $property => $value) {
227228
if (isset($value) && !in_array($property, $removeproperties)) {
228-
$profile->set($property, $value);
229+
if (property_exists($profile, $property)) {
230+
$profile->set($property, $value);
231+
}
229232
}
230233
}
231234

classes/sample_set.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class sample_set {
3030
/** @var float Starting time of the sample set. */
3131
public $starttime;
3232

33-
/** @var array An array of \ExcimerLogEntry objects. */
33+
/** @var array An array of sample objects. It could contain memory usage samples or tasks samples */
3434
public $samples = [];
3535

3636
/** @var int Sample limit. */
@@ -126,7 +126,7 @@ private function merge_memory_usage_sample_set() {
126126
} else {
127127
$newsamples[] = [
128128
'sampleindex' => $this->samples[$i]['sampleindex'],
129-
'value' => ($this->samples[$i]['value'] + $this->samples[$i + 1]['value']) / 2.0,
129+
'value' => max($this->samples[$i]['value'], $this->samples[$i + 1]['value']),
130130
];
131131
}
132132
}
@@ -149,7 +149,7 @@ private function merge_excimer_sample_set() {
149149
$trace = $this->samples[$i + 1]['trace'];
150150
}
151151
$newsamples[] = [
152-
'eventcount' => ($this->samples[$i]['eventcount'] + $this->samples[$i + 1]['eventcount']),
152+
'eventcount' => ceil(($this->samples[$i]['eventcount'] + $this->samples[$i + 1]['eventcount']) / 2),
153153
'trace' => $trace,
154154
];
155155
}

0 commit comments

Comments
 (0)