osprey 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/flamegraph.svg ADDED
@@ -0,0 +1,491 @@
1
+ <?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" width="1200" height="390" onload="init(evt)" viewBox="0 0 1200 390" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fg="http://github.com/jonhoo/inferno"><!--Flame graph stack visualization. See https://github.com/brendangregg/FlameGraph for latest version, and http://www.brendangregg.com/flamegraphs.html for examples.--><!--NOTES: --><defs><linearGradient id="background" y1="0" y2="1" x1="0" x2="0"><stop stop-color="#eeeeee" offset="5%"/><stop stop-color="#eeeeb0" offset="95%"/></linearGradient></defs><style type="text/css">
2
+ text { font-family:monospace; font-size:12px }
3
+ #title { text-anchor:middle; font-size:17px; }
4
+ #matched { text-anchor:end; }
5
+ #search { text-anchor:end; opacity:0.1; cursor:pointer; }
6
+ #search:hover, #search.show { opacity:1; }
7
+ #subtitle { text-anchor:middle; font-color:rgb(160,160,160); }
8
+ #unzoom { cursor:pointer; }
9
+ #frames > *:hover { stroke:black; stroke-width:0.5; cursor:pointer; }
10
+ .hide { display:none; }
11
+ .parent { opacity:0.5; }
12
+ </style><script type="text/ecmascript"><![CDATA[
13
+ var nametype = 'Function:';
14
+ var fontsize = 12;
15
+ var fontwidth = 0.59;
16
+ var xpad = 10;
17
+ var inverted = false;
18
+ var searchcolor = 'rgb(230,0,230)';
19
+ var fluiddrawing = true;
20
+ var truncate_text_right = false;
21
+ ]]><![CDATA["use strict";
22
+ var details, searchbtn, unzoombtn, matchedtxt, svg, searching, frames, known_font_width;
23
+ function init(evt) {
24
+ details = document.getElementById("details").firstChild;
25
+ searchbtn = document.getElementById("search");
26
+ unzoombtn = document.getElementById("unzoom");
27
+ matchedtxt = document.getElementById("matched");
28
+ svg = document.getElementsByTagName("svg")[0];
29
+ frames = document.getElementById("frames");
30
+ known_font_width = get_monospace_width(frames);
31
+ total_samples = parseInt(frames.attributes.total_samples.value);
32
+ searching = 0;
33
+
34
+ // Use GET parameters to restore a flamegraph's state.
35
+ var restore_state = function() {
36
+ var params = get_params();
37
+ if (params.x && params.y)
38
+ zoom(find_group(document.querySelector('[*|x="' + params.x + '"][y="' + params.y + '"]')));
39
+ if (params.s)
40
+ search(params.s);
41
+ };
42
+
43
+ if (fluiddrawing) {
44
+ // Make width dynamic so the SVG fits its parent's width.
45
+ svg.removeAttribute("width");
46
+ // Edge requires us to have a viewBox that gets updated with size changes.
47
+ var isEdge = /Edge\/\d./i.test(navigator.userAgent);
48
+ if (!isEdge) {
49
+ svg.removeAttribute("viewBox");
50
+ }
51
+ var update_for_width_change = function() {
52
+ if (isEdge) {
53
+ svg.attributes.viewBox.value = "0 0 " + svg.width.baseVal.value + " " + svg.height.baseVal.value;
54
+ }
55
+
56
+ // Keep consistent padding on left and right of frames container.
57
+ frames.attributes.width.value = svg.width.baseVal.value - xpad * 2;
58
+
59
+ // Text truncation needs to be adjusted for the current width.
60
+ update_text_for_elements(frames.children);
61
+
62
+ // Keep search elements at a fixed distance from right edge.
63
+ var svgWidth = svg.width.baseVal.value;
64
+ searchbtn.attributes.x.value = svgWidth - xpad;
65
+ matchedtxt.attributes.x.value = svgWidth - xpad;
66
+ };
67
+ window.addEventListener('resize', function() {
68
+ update_for_width_change();
69
+ });
70
+ // This needs to be done asynchronously for Safari to work.
71
+ setTimeout(function() {
72
+ unzoom();
73
+ update_for_width_change();
74
+ restore_state();
75
+ }, 0);
76
+ } else {
77
+ restore_state();
78
+ }
79
+ }
80
+ // event listeners
81
+ window.addEventListener("click", function(e) {
82
+ var target = find_group(e.target);
83
+ if (target) {
84
+ if (target.nodeName == "a") {
85
+ if (e.ctrlKey === false) return;
86
+ e.preventDefault();
87
+ }
88
+ if (target.classList.contains("parent")) unzoom();
89
+ zoom(target);
90
+
91
+ // set parameters for zoom state
92
+ var el = target.querySelector("rect");
93
+ if (el && el.attributes && el.attributes.y && el.attributes["fg:x"]) {
94
+ var params = get_params()
95
+ params.x = el.attributes["fg:x"].value;
96
+ params.y = el.attributes.y.value;
97
+ history.replaceState(null, null, parse_params(params));
98
+ }
99
+ }
100
+ else if (e.target.id == "unzoom") {
101
+ unzoom();
102
+
103
+ // remove zoom state
104
+ var params = get_params();
105
+ if (params.x) delete params.x;
106
+ if (params.y) delete params.y;
107
+ history.replaceState(null, null, parse_params(params));
108
+ }
109
+ else if (e.target.id == "search") search_prompt();
110
+ }, false)
111
+ // mouse-over for info
112
+ // show
113
+ window.addEventListener("mouseover", function(e) {
114
+ var target = find_group(e.target);
115
+ if (target) details.nodeValue = nametype + " " + g_to_text(target);
116
+ }, false)
117
+ // clear
118
+ window.addEventListener("mouseout", function(e) {
119
+ var target = find_group(e.target);
120
+ if (target) details.nodeValue = ' ';
121
+ }, false)
122
+ // ctrl-F for search
123
+ window.addEventListener("keydown",function (e) {
124
+ if (e.keyCode === 114 || (e.ctrlKey && e.keyCode === 70)) {
125
+ e.preventDefault();
126
+ search_prompt();
127
+ }
128
+ }, false)
129
+ // functions
130
+ function get_params() {
131
+ var params = {};
132
+ var paramsarr = window.location.search.substr(1).split('&');
133
+ for (var i = 0; i < paramsarr.length; ++i) {
134
+ var tmp = paramsarr[i].split("=");
135
+ if (!tmp[0] || !tmp[1]) continue;
136
+ params[tmp[0]] = decodeURIComponent(tmp[1]);
137
+ }
138
+ return params;
139
+ }
140
+ function parse_params(params) {
141
+ var uri = "?";
142
+ for (var key in params) {
143
+ uri += key + '=' + encodeURIComponent(params[key]) + '&';
144
+ }
145
+ if (uri.slice(-1) == "&")
146
+ uri = uri.substring(0, uri.length - 1);
147
+ if (uri == '?')
148
+ uri = window.location.href.split('?')[0];
149
+ return uri;
150
+ }
151
+ function find_child(node, selector) {
152
+ var children = node.querySelectorAll(selector);
153
+ if (children.length) return children[0];
154
+ return;
155
+ }
156
+ function find_group(node) {
157
+ var parent = node.parentElement;
158
+ if (!parent) return;
159
+ if (parent.id == "frames") return node;
160
+ return find_group(parent);
161
+ }
162
+ function orig_save(e, attr, val) {
163
+ if (e.attributes["fg:orig_" + attr] != undefined) return;
164
+ if (e.attributes[attr] == undefined) return;
165
+ if (val == undefined) val = e.attributes[attr].value;
166
+ e.setAttribute("fg:orig_" + attr, val);
167
+ }
168
+ function orig_load(e, attr) {
169
+ if (e.attributes["fg:orig_"+attr] == undefined) return;
170
+ e.attributes[attr].value = e.attributes["fg:orig_" + attr].value;
171
+ e.removeAttribute("fg:orig_" + attr);
172
+ }
173
+ function g_to_text(e) {
174
+ var text = find_child(e, "title").firstChild.nodeValue;
175
+ return (text)
176
+ }
177
+ function g_to_func(e) {
178
+ var func = g_to_text(e);
179
+ // if there's any manipulation we want to do to the function
180
+ // name before it's searched, do it here before returning.
181
+ return (func);
182
+ }
183
+ function get_monospace_width(frames) {
184
+ // Given the id="frames" element, return the width of text characters if
185
+ // this is a monospace font, otherwise return 0.
186
+ text = find_child(frames.children[0], "text");
187
+ originalContent = text.textContent;
188
+ text.textContent = "!";
189
+ bangWidth = text.getComputedTextLength();
190
+ text.textContent = "W";
191
+ wWidth = text.getComputedTextLength();
192
+ text.textContent = originalContent;
193
+ if (bangWidth === wWidth) {
194
+ return bangWidth;
195
+ } else {
196
+ return 0;
197
+ }
198
+ }
199
+ function update_text_for_elements(elements) {
200
+ // In order to render quickly in the browser, you want to do one pass of
201
+ // reading attributes, and one pass of mutating attributes. See
202
+ // https://web.dev/avoid-large-complex-layouts-and-layout-thrashing/ for details.
203
+
204
+ // Fall back to inefficient calculation, if we're variable-width font.
205
+ // TODO This should be optimized somehow too.
206
+ if (known_font_width === 0) {
207
+ for (var i = 0; i < elements.length; i++) {
208
+ update_text(elements[i]);
209
+ }
210
+ return;
211
+ }
212
+
213
+ var textElemNewAttributes = [];
214
+ for (var i = 0; i < elements.length; i++) {
215
+ var e = elements[i];
216
+ var r = find_child(e, "rect");
217
+ var t = find_child(e, "text");
218
+ var w = parseFloat(r.attributes.width.value) * frames.attributes.width.value / 100 - 3;
219
+ var txt = find_child(e, "title").textContent.replace(/\([^(]*\)$/,"");
220
+ var newX = format_percent((parseFloat(r.attributes.x.value) + (100 * 3 / frames.attributes.width.value)));
221
+
222
+ // Smaller than this size won't fit anything
223
+ if (w < 2 * known_font_width) {
224
+ textElemNewAttributes.push([newX, ""]);
225
+ continue;
226
+ }
227
+
228
+ // Fit in full text width
229
+ if (txt.length * known_font_width < w) {
230
+ textElemNewAttributes.push([newX, txt]);
231
+ continue;
232
+ }
233
+
234
+ var substringLength = Math.floor(w / known_font_width) - 2;
235
+ if (truncate_text_right) {
236
+ // Truncate the right side of the text.
237
+ textElemNewAttributes.push([newX, txt.substring(0, substringLength) + ".."]);
238
+ continue;
239
+ } else {
240
+ // Truncate the left side of the text.
241
+ textElemNewAttributes.push([newX, ".." + txt.substring(txt.length - substringLength, txt.length)]);
242
+ continue;
243
+ }
244
+ }
245
+
246
+ console.assert(textElemNewAttributes.length === elements.length, "Resize failed, please file a bug at https://github.com/jonhoo/inferno/");
247
+
248
+ // Now that we know new textContent, set it all in one go so we don't refresh a bazillion times.
249
+ for (var i = 0; i < elements.length; i++) {
250
+ var e = elements[i];
251
+ var values = textElemNewAttributes[i];
252
+ var t = find_child(e, "text");
253
+ t.attributes.x.value = values[0];
254
+ t.textContent = values[1];
255
+ }
256
+ }
257
+
258
+ function update_text(e) {
259
+ var r = find_child(e, "rect");
260
+ var t = find_child(e, "text");
261
+ var w = parseFloat(r.attributes.width.value) * frames.attributes.width.value / 100 - 3;
262
+ var txt = find_child(e, "title").textContent.replace(/\([^(]*\)$/,"");
263
+ t.attributes.x.value = format_percent((parseFloat(r.attributes.x.value) + (100 * 3 / frames.attributes.width.value)));
264
+
265
+ // Smaller than this size won't fit anything
266
+ if (w < 2 * fontsize * fontwidth) {
267
+ t.textContent = "";
268
+ return;
269
+ }
270
+ t.textContent = txt;
271
+ // Fit in full text width
272
+ if (t.getComputedTextLength() < w)
273
+ return;
274
+ if (truncate_text_right) {
275
+ // Truncate the right side of the text.
276
+ for (var x = txt.length - 2; x > 0; x--) {
277
+ if (t.getSubStringLength(0, x + 2) <= w) {
278
+ t.textContent = txt.substring(0, x) + "..";
279
+ return;
280
+ }
281
+ }
282
+ } else {
283
+ // Truncate the left side of the text.
284
+ for (var x = 2; x < txt.length; x++) {
285
+ if (t.getSubStringLength(x - 2, txt.length) <= w) {
286
+ t.textContent = ".." + txt.substring(x, txt.length);
287
+ return;
288
+ }
289
+ }
290
+ }
291
+ t.textContent = "";
292
+ }
293
+ // zoom
294
+ function zoom_reset(e) {
295
+ if (e.tagName == "rect") {
296
+ e.attributes.x.value = format_percent(100 * parseInt(e.attributes["fg:x"].value) / total_samples);
297
+ e.attributes.width.value = format_percent(100 * parseInt(e.attributes["fg:w"].value) / total_samples);
298
+ }
299
+ if (e.childNodes == undefined) return;
300
+ for(var i = 0, c = e.childNodes; i < c.length; i++) {
301
+ zoom_reset(c[i]);
302
+ }
303
+ }
304
+ function zoom_child(e, x, zoomed_width_samples) {
305
+ if (e.tagName == "text") {
306
+ var parent_x = parseFloat(find_child(e.parentNode, "rect[x]").attributes.x.value);
307
+ e.attributes.x.value = format_percent(parent_x + (100 * 3 / frames.attributes.width.value));
308
+ } else if (e.tagName == "rect") {
309
+ e.attributes.x.value = format_percent(100 * (parseInt(e.attributes["fg:x"].value) - x) / zoomed_width_samples);
310
+ e.attributes.width.value = format_percent(100 * parseInt(e.attributes["fg:w"].value) / zoomed_width_samples);
311
+ }
312
+ if (e.childNodes == undefined) return;
313
+ for(var i = 0, c = e.childNodes; i < c.length; i++) {
314
+ zoom_child(c[i], x, zoomed_width_samples);
315
+ }
316
+ }
317
+ function zoom_parent(e) {
318
+ if (e.attributes) {
319
+ if (e.attributes.x != undefined) {
320
+ e.attributes.x.value = "0.0%";
321
+ }
322
+ if (e.attributes.width != undefined) {
323
+ e.attributes.width.value = "100.0%";
324
+ }
325
+ }
326
+ if (e.childNodes == undefined) return;
327
+ for(var i = 0, c = e.childNodes; i < c.length; i++) {
328
+ zoom_parent(c[i]);
329
+ }
330
+ }
331
+ function zoom(node) {
332
+ var attr = find_child(node, "rect").attributes;
333
+ var width = parseInt(attr["fg:w"].value);
334
+ var xmin = parseInt(attr["fg:x"].value);
335
+ var xmax = xmin + width;
336
+ var ymin = parseFloat(attr.y.value);
337
+ unzoombtn.classList.remove("hide");
338
+ var el = frames.children;
339
+ var to_update_text = [];
340
+ for (var i = 0; i < el.length; i++) {
341
+ var e = el[i];
342
+ var a = find_child(e, "rect").attributes;
343
+ var ex = parseInt(a["fg:x"].value);
344
+ var ew = parseInt(a["fg:w"].value);
345
+ // Is it an ancestor
346
+ if (!inverted) {
347
+ var upstack = parseFloat(a.y.value) > ymin;
348
+ } else {
349
+ var upstack = parseFloat(a.y.value) < ymin;
350
+ }
351
+ if (upstack) {
352
+ // Direct ancestor
353
+ if (ex <= xmin && (ex+ew) >= xmax) {
354
+ e.classList.add("parent");
355
+ zoom_parent(e);
356
+ to_update_text.push(e);
357
+ }
358
+ // not in current path
359
+ else
360
+ e.classList.add("hide");
361
+ }
362
+ // Children maybe
363
+ else {
364
+ // no common path
365
+ if (ex < xmin || ex >= xmax) {
366
+ e.classList.add("hide");
367
+ }
368
+ else {
369
+ zoom_child(e, xmin, width);
370
+ to_update_text.push(e);
371
+ }
372
+ }
373
+ }
374
+ update_text_for_elements(to_update_text);
375
+ }
376
+ function unzoom() {
377
+ unzoombtn.classList.add("hide");
378
+ var el = frames.children;
379
+ for(var i = 0; i < el.length; i++) {
380
+ el[i].classList.remove("parent");
381
+ el[i].classList.remove("hide");
382
+ zoom_reset(el[i]);
383
+ }
384
+ update_text_for_elements(el);
385
+ }
386
+ // search
387
+ function reset_search() {
388
+ var el = document.querySelectorAll("#frames rect");
389
+ for (var i = 0; i < el.length; i++) {
390
+ orig_load(el[i], "fill")
391
+ }
392
+ var params = get_params();
393
+ delete params.s;
394
+ history.replaceState(null, null, parse_params(params));
395
+ }
396
+ function search_prompt() {
397
+ if (!searching) {
398
+ var term = prompt("Enter a search term (regexp " +
399
+ "allowed, eg: ^ext4_)", "");
400
+ if (term != null) {
401
+ search(term)
402
+ }
403
+ } else {
404
+ reset_search();
405
+ searching = 0;
406
+ searchbtn.classList.remove("show");
407
+ searchbtn.firstChild.nodeValue = "Search"
408
+ matchedtxt.classList.add("hide");
409
+ matchedtxt.firstChild.nodeValue = ""
410
+ }
411
+ }
412
+ function search(term) {
413
+ var re = new RegExp(term);
414
+ var el = frames.children;
415
+ var matches = new Object();
416
+ var maxwidth = 0;
417
+ for (var i = 0; i < el.length; i++) {
418
+ var e = el[i];
419
+ // Skip over frames which are either not visible, or below the zoomed-to frame
420
+ if (e.classList.contains("hide") || e.classList.contains("parent")) {
421
+ continue;
422
+ }
423
+ var func = g_to_func(e);
424
+ var rect = find_child(e, "rect");
425
+ if (func == null || rect == null)
426
+ continue;
427
+ // Save max width. Only works as we have a root frame
428
+ var w = parseInt(rect.attributes["fg:w"].value);
429
+ if (w > maxwidth)
430
+ maxwidth = w;
431
+ if (func.match(re)) {
432
+ // highlight
433
+ var x = parseInt(rect.attributes["fg:x"].value);
434
+ orig_save(rect, "fill");
435
+ rect.attributes.fill.value = searchcolor;
436
+ // remember matches
437
+ if (matches[x] == undefined) {
438
+ matches[x] = w;
439
+ } else {
440
+ if (w > matches[x]) {
441
+ // overwrite with parent
442
+ matches[x] = w;
443
+ }
444
+ }
445
+ searching = 1;
446
+ }
447
+ }
448
+ if (!searching)
449
+ return;
450
+ var params = get_params();
451
+ params.s = term;
452
+ history.replaceState(null, null, parse_params(params));
453
+
454
+ searchbtn.classList.add("show");
455
+ searchbtn.firstChild.nodeValue = "Reset Search";
456
+ // calculate percent matched, excluding vertical overlap
457
+ var count = 0;
458
+ var lastx = -1;
459
+ var lastw = 0;
460
+ var keys = Array();
461
+ for (k in matches) {
462
+ if (matches.hasOwnProperty(k))
463
+ keys.push(k);
464
+ }
465
+ // sort the matched frames by their x location
466
+ // ascending, then width descending
467
+ keys.sort(function(a, b){
468
+ return a - b;
469
+ });
470
+ // Step through frames saving only the biggest bottom-up frames
471
+ // thanks to the sort order. This relies on the tree property
472
+ // where children are always smaller than their parents.
473
+ for (var k in keys) {
474
+ var x = parseInt(keys[k]);
475
+ var w = matches[keys[k]];
476
+ if (x >= lastx + lastw) {
477
+ count += w;
478
+ lastx = x;
479
+ lastw = w;
480
+ }
481
+ }
482
+ // display matched percent
483
+ matchedtxt.classList.remove("hide");
484
+ var pct = 100 * count / maxwidth;
485
+ if (pct != 100) pct = pct.toFixed(1);
486
+ matchedtxt.firstChild.nodeValue = "Matched: " + pct + "%";
487
+ }
488
+ function format_percent(n) {
489
+ return n.toFixed(4) + "%";
490
+ }
491
+ ]]></script><rect x="0" y="0" width="100%" height="390" fill="url(#background)"/><text id="title" fill="rgb(0,0,0)" x="50.0000%" y="24.00">Flame Graph</text><text id="details" fill="rgb(0,0,0)" x="10" y="373.00"> </text><text id="unzoom" class="hide" fill="rgb(0,0,0)" x="10" y="24.00">Reset Zoom</text><text id="search" fill="rgb(0,0,0)" x="1190" y="24.00">Search</text><text id="matched" fill="rgb(0,0,0)" x="1190" y="373.00"> </text><svg id="frames" x="10" width="1180" total_samples="1283"><g><title>libruby.3.4.dylib`rb_nogvl (1 samples, 0.08%)</title><rect x="0.0000%" y="181" width="0.0779%" height="15" fill="rgb(227,0,7)" fg:x="0" fg:w="1"/><text x="0.2500%" y="191.50"></text></g><g><title>libsystem_malloc.dylib`_free (2 samples, 0.16%)</title><rect x="0.0779%" y="181" width="0.1559%" height="15" fill="rgb(217,0,24)" fg:x="1" fg:w="2"/><text x="0.3279%" y="191.50"></text></g><g><title>libsystem_malloc.dylib`default_zone_free_definite_size (5 samples, 0.39%)</title><rect x="0.2338%" y="181" width="0.3897%" height="15" fill="rgb(221,193,54)" fg:x="3" fg:w="5"/><text x="0.4838%" y="191.50"></text></g><g><title>libsystem_malloc.dylib`nanov2_forked_free (1 samples, 0.08%)</title><rect x="0.6235%" y="181" width="0.0779%" height="15" fill="rgb(248,212,6)" fg:x="8" fg:w="1"/><text x="0.8735%" y="191.50"></text></g><g><title>libruby.3.4.dylib`blocking_region_begin (1 samples, 0.08%)</title><rect x="0.7794%" y="165" width="0.0779%" height="15" fill="rgb(208,68,35)" fg:x="10" fg:w="1"/><text x="1.0294%" y="175.50"></text></g><g><title>libruby.3.4.dylib`rb_current_ec (1 samples, 0.08%)</title><rect x="0.8574%" y="165" width="0.0779%" height="15" fill="rgb(232,128,0)" fg:x="11" fg:w="1"/><text x="1.1074%" y="175.50"></text></g><g><title>libruby.3.4.dylib`rb_errno (2 samples, 0.16%)</title><rect x="0.9353%" y="165" width="0.1559%" height="15" fill="rgb(207,160,47)" fg:x="12" fg:w="2"/><text x="1.1853%" y="175.50"></text></g><g><title>libdyld.dylib`tlv_get_addr (1 samples, 0.08%)</title><rect x="1.4030%" y="149" width="0.0779%" height="15" fill="rgb(228,23,34)" fg:x="18" fg:w="1"/><text x="1.6530%" y="159.50"></text></g><g><title>libruby.3.4.dylib`DYLD-STUB$$__error (2 samples, 0.16%)</title><rect x="1.4809%" y="149" width="0.1559%" height="15" fill="rgb(218,30,26)" fg:x="19" fg:w="2"/><text x="1.7309%" y="159.50"></text></g><g><title>libruby.3.4.dylib`blocking_region_begin (1 samples, 0.08%)</title><rect x="1.6368%" y="149" width="0.0779%" height="15" fill="rgb(220,122,19)" fg:x="21" fg:w="1"/><text x="1.8868%" y="159.50"></text></g><g><title>libsystem_pthread.dylib`pthread_mutex_lock (1 samples, 0.08%)</title><rect x="1.6368%" y="133" width="0.0779%" height="15" fill="rgb(250,228,42)" fg:x="21" fg:w="1"/><text x="1.8868%" y="143.50"></text></g><g><title>libruby.3.4.dylib`thread_sched_setup_running_threads (1 samples, 0.08%)</title><rect x="1.7147%" y="117" width="0.0779%" height="15" fill="rgb(240,193,28)" fg:x="22" fg:w="1"/><text x="1.9647%" y="127.50"></text></g><g><title>libsystem_pthread.dylib`pthread_mutex_lock (1 samples, 0.08%)</title><rect x="1.7147%" y="101" width="0.0779%" height="15" fill="rgb(216,20,37)" fg:x="22" fg:w="1"/><text x="1.9647%" y="111.50"></text></g><g><title>libruby.3.4.dylib`thread_sched_to_running (2 samples, 0.16%)</title><rect x="1.7147%" y="133" width="0.1559%" height="15" fill="rgb(206,188,39)" fg:x="22" fg:w="2"/><text x="1.9647%" y="143.50"></text></g><g><title>libsystem_pthread.dylib`pthread_mutex_lock (1 samples, 0.08%)</title><rect x="1.7927%" y="117" width="0.0779%" height="15" fill="rgb(217,207,13)" fg:x="23" fg:w="1"/><text x="2.0427%" y="127.50"></text></g><g><title>libruby.3.4.dylib`thread_sched_wait_running_turn (4 samples, 0.31%)</title><rect x="1.8706%" y="133" width="0.3118%" height="15" fill="rgb(231,73,38)" fg:x="24" fg:w="4"/><text x="2.1206%" y="143.50"></text></g><g><title>libruby.3.4.dylib`blocking_region_end (7 samples, 0.55%)</title><rect x="1.7147%" y="149" width="0.5456%" height="15" fill="rgb(225,20,46)" fg:x="22" fg:w="7"/><text x="1.9647%" y="159.50"></text></g><g><title>libsystem_pthread.dylib`pthread_mutex_lock (1 samples, 0.08%)</title><rect x="2.1824%" y="133" width="0.0779%" height="15" fill="rgb(210,31,41)" fg:x="28" fg:w="1"/><text x="2.4324%" y="143.50"></text></g><g><title>libruby.3.4.dylib`rb_ractor_blocking_threads_dec (3 samples, 0.23%)</title><rect x="2.2603%" y="149" width="0.2338%" height="15" fill="rgb(221,200,47)" fg:x="29" fg:w="3"/><text x="2.5103%" y="159.50"></text></g><g><title>libruby.3.4.dylib`thread_sched_setup_running_threads (1 samples, 0.08%)</title><rect x="2.4942%" y="149" width="0.0779%" height="15" fill="rgb(226,26,5)" fg:x="32" fg:w="1"/><text x="2.7442%" y="159.50"></text></g><g><title>libsystem_kernel.dylib`__error (2 samples, 0.16%)</title><rect x="2.5721%" y="149" width="0.1559%" height="15" fill="rgb(249,33,26)" fg:x="33" fg:w="2"/><text x="2.8221%" y="159.50"></text></g><g><title>libsystem_malloc.dylib`malloc (1 samples, 0.08%)</title><rect x="2.7280%" y="149" width="0.0779%" height="15" fill="rgb(235,183,28)" fg:x="35" fg:w="1"/><text x="2.9780%" y="159.50"></text></g><g><title>libsystem_malloc.dylib`nanov2_forked_malloc (7 samples, 0.55%)</title><rect x="2.8059%" y="149" width="0.5456%" height="15" fill="rgb(221,5,38)" fg:x="36" fg:w="7"/><text x="3.0559%" y="159.50"></text></g><g><title>libsystem_malloc.dylib`szone_malloc (1 samples, 0.08%)</title><rect x="3.3515%" y="149" width="0.0779%" height="15" fill="rgb(247,18,42)" fg:x="43" fg:w="1"/><text x="3.6015%" y="159.50"></text></g><g><title>libsystem_malloc.dylib`szone_malloc_should_clear (3 samples, 0.23%)</title><rect x="3.4295%" y="149" width="0.2338%" height="15" fill="rgb(241,131,45)" fg:x="44" fg:w="3"/><text x="3.6795%" y="159.50"></text></g><g><title>osprey.bundle`__rust_alloc (2 samples, 0.16%)</title><rect x="3.6633%" y="149" width="0.1559%" height="15" fill="rgb(249,31,29)" fg:x="47" fg:w="2"/><text x="3.9133%" y="159.50"></text></g><g><title>libsystem_malloc.dylib`small_malloc_should_clear (1 samples, 0.08%)</title><rect x="4.0530%" y="133" width="0.0779%" height="15" fill="rgb(225,111,53)" fg:x="52" fg:w="1"/><text x="4.3030%" y="143.50"></text></g><g><title>libsystem_malloc.dylib`rack_get_thread_index (1 samples, 0.08%)</title><rect x="4.1309%" y="117" width="0.0779%" height="15" fill="rgb(238,160,17)" fg:x="53" fg:w="1"/><text x="4.3809%" y="127.50"></text></g><g><title>libsystem_malloc.dylib`szone_malloc_should_clear (2 samples, 0.16%)</title><rect x="4.1309%" y="133" width="0.1559%" height="15" fill="rgb(214,148,48)" fg:x="53" fg:w="2"/><text x="4.3809%" y="143.50"></text></g><g><title>libsystem_malloc.dylib`small_malloc_should_clear (1 samples, 0.08%)</title><rect x="4.2089%" y="117" width="0.0779%" height="15" fill="rgb(232,36,49)" fg:x="54" fg:w="1"/><text x="4.4589%" y="127.50"></text></g><g><title>libsystem_pthread.dylib`cthread_yield (2 samples, 0.16%)</title><rect x="4.3648%" y="117" width="0.1559%" height="15" fill="rgb(209,103,24)" fg:x="56" fg:w="2"/><text x="4.6148%" y="127.50"></text></g><g><title>osprey.bundle`DYLD-STUB$$sched_yield (1 samples, 0.08%)</title><rect x="4.5207%" y="117" width="0.0779%" height="15" fill="rgb(229,88,8)" fg:x="58" fg:w="1"/><text x="4.7707%" y="127.50"></text></g><g><title>libsystem_c.dylib`clock_gettime (1 samples, 0.08%)</title><rect x="21.9797%" y="101" width="0.0779%" height="15" fill="rgb(213,181,19)" fg:x="282" fg:w="1"/><text x="22.2297%" y="111.50"></text></g><g><title>libsystem_kernel.dylib`swtch_pri (672 samples, 52.38%)</title><rect x="22.0577%" y="101" width="52.3772%" height="15" fill="rgb(254,191,54)" fg:x="283" fg:w="672"/><text x="22.3077%" y="111.50">libsystem_kernel.dylib`swtch_pri</text></g><g><title>libsystem_pthread.dylib`cthread_yield (2 samples, 0.16%)</title><rect x="74.4349%" y="101" width="0.1559%" height="15" fill="rgb(241,83,37)" fg:x="955" fg:w="2"/><text x="74.6849%" y="111.50"></text></g><g><title>osprey.bundle`DYLD-STUB$$clock_gettime (1 samples, 0.08%)</title><rect x="74.5908%" y="101" width="0.0779%" height="15" fill="rgb(233,36,39)" fg:x="957" fg:w="1"/><text x="74.8408%" y="111.50"></text></g><g><title>libsystem_c.dylib`clock_gettime (1 samples, 0.08%)</title><rect x="74.9026%" y="85" width="0.0779%" height="15" fill="rgb(226,3,54)" fg:x="961" fg:w="1"/><text x="75.1526%" y="95.50"></text></g><g><title>libsystem_pthread.dylib`pthread_mutex_unlock (1 samples, 0.08%)</title><rect x="74.9805%" y="85" width="0.0779%" height="15" fill="rgb(245,192,40)" fg:x="962" fg:w="1"/><text x="75.2305%" y="95.50"></text></g><g><title>libsystem_c.dylib`DYLD-STUB$$mach_timebase_info (1 samples, 0.08%)</title><rect x="75.1364%" y="53" width="0.0779%" height="15" fill="rgb(238,167,29)" fg:x="964" fg:w="1"/><text x="75.3864%" y="63.50"></text></g><g><title>libsystem_c.dylib`clock_gettime_nsec_np (1 samples, 0.08%)</title><rect x="75.2143%" y="53" width="0.0779%" height="15" fill="rgb(232,182,51)" fg:x="965" fg:w="1"/><text x="75.4643%" y="63.50"></text></g><g><title>libsystem_kernel.dylib`mach_timebase_info (1 samples, 0.08%)</title><rect x="75.2143%" y="37" width="0.0779%" height="15" fill="rgb(231,60,39)" fg:x="965" fg:w="1"/><text x="75.4643%" y="47.50"></text></g><g><title>libsystem_kernel.dylib`mach_absolute_time (13 samples, 1.01%)</title><rect x="75.2923%" y="53" width="1.0133%" height="15" fill="rgb(208,69,12)" fg:x="966" fg:w="13"/><text x="75.5423%" y="63.50"></text></g><g><title>osprey.bundle`std::sys::pal::unix::time::Timespec::now (19 samples, 1.48%)</title><rect x="75.0585%" y="85" width="1.4809%" height="15" fill="rgb(235,93,37)" fg:x="963" fg:w="19"/><text x="75.3085%" y="95.50"></text></g><g><title>libsystem_c.dylib`clock_gettime (19 samples, 1.48%)</title><rect x="75.0585%" y="69" width="1.4809%" height="15" fill="rgb(213,116,39)" fg:x="963" fg:w="19"/><text x="75.3085%" y="79.50"></text></g><g><title>libsystem_kernel.dylib`mach_timebase_info (3 samples, 0.23%)</title><rect x="76.3055%" y="53" width="0.2338%" height="15" fill="rgb(222,207,29)" fg:x="979" fg:w="3"/><text x="76.5555%" y="63.50"></text></g><g><title>libdispatch.dylib`_dispatch_sema4_timedwait (3 samples, 0.23%)</title><rect x="76.9291%" y="53" width="0.2338%" height="15" fill="rgb(206,96,30)" fg:x="987" fg:w="3"/><text x="77.1791%" y="63.50"></text></g><g><title>libsystem_kernel.dylib`mach_absolute_time (1 samples, 0.08%)</title><rect x="77.0850%" y="37" width="0.0779%" height="15" fill="rgb(218,138,4)" fg:x="989" fg:w="1"/><text x="77.3350%" y="47.50"></text></g><g><title>libdispatch.dylib`_dispatch_timeout (1 samples, 0.08%)</title><rect x="77.1629%" y="53" width="0.0779%" height="15" fill="rgb(250,191,14)" fg:x="990" fg:w="1"/><text x="77.4129%" y="63.50"></text></g><g><title>libdispatch.dylib`_dispatch_semaphore_wait_slow (229 samples, 17.85%)</title><rect x="76.6952%" y="69" width="17.8488%" height="15" fill="rgb(239,60,40)" fg:x="984" fg:w="229"/><text x="76.9452%" y="79.50">libdispatch.dylib`_dispatch_..</text></g><g><title>libsystem_kernel.dylib`semaphore_timedwait_trap (222 samples, 17.30%)</title><rect x="77.2408%" y="53" width="17.3032%" height="15" fill="rgb(206,27,48)" fg:x="991" fg:w="222"/><text x="77.4908%" y="63.50">libsystem_kernel.dylib`sema..</text></g><g><title>osprey.bundle`crossbeam_channel::flavors::list::Channel&lt;T&gt;::recv::_{{closure}} (258 samples, 20.11%)</title><rect x="74.6687%" y="101" width="20.1091%" height="15" fill="rgb(225,35,8)" fg:x="958" fg:w="258"/><text x="74.9187%" y="111.50">osprey.bundle`crossbeam_channel:..</text></g><g><title>osprey.bundle`std::thread::park_timeout (234 samples, 18.24%)</title><rect x="76.5394%" y="85" width="18.2385%" height="15" fill="rgb(250,213,24)" fg:x="982" fg:w="234"/><text x="76.7894%" y="95.50">osprey.bundle`std::thread::p..</text></g><g><title>libsystem_kernel.dylib`mach_absolute_time (3 samples, 0.23%)</title><rect x="94.5440%" y="69" width="0.2338%" height="15" fill="rgb(247,123,22)" fg:x="1213" fg:w="3"/><text x="94.7940%" y="79.50"></text></g><g><title>osprey.bundle`crossbeam_channel::flavors::list::Channel&lt;T&gt;::start_recv (4 samples, 0.31%)</title><rect x="94.7779%" y="101" width="0.3118%" height="15" fill="rgb(231,138,38)" fg:x="1216" fg:w="4"/><text x="95.0279%" y="111.50"></text></g><g><title>libsystem_c.dylib`clock_gettime_nsec_np (1 samples, 0.08%)</title><rect x="95.1676%" y="69" width="0.0779%" height="15" fill="rgb(231,145,46)" fg:x="1221" fg:w="1"/><text x="95.4176%" y="79.50"></text></g><g><title>osprey.bundle`std::sys::pal::unix::time::Timespec::now (4 samples, 0.31%)</title><rect x="95.0896%" y="101" width="0.3118%" height="15" fill="rgb(251,118,11)" fg:x="1220" fg:w="4"/><text x="95.3396%" y="111.50"></text></g><g><title>libsystem_c.dylib`clock_gettime (3 samples, 0.23%)</title><rect x="95.1676%" y="85" width="0.2338%" height="15" fill="rgb(217,147,25)" fg:x="1221" fg:w="3"/><text x="95.4176%" y="95.50"></text></g><g><title>libsystem_kernel.dylib`mach_absolute_time (2 samples, 0.16%)</title><rect x="95.2455%" y="69" width="0.1559%" height="15" fill="rgb(247,81,37)" fg:x="1222" fg:w="2"/><text x="95.4955%" y="79.50"></text></g><g><title>osprey.bundle`crossbeam_channel::flavors::list::Channel&lt;T&gt;::recv (1,166 samples, 90.88%)</title><rect x="4.5986%" y="117" width="90.8807%" height="15" fill="rgb(209,12,38)" fg:x="59" fg:w="1166"/><text x="4.8486%" y="127.50">osprey.bundle`crossbeam_channel::flavors::list::Channel&lt;T&gt;::recv</text></g><g><title>osprey.bundle`std::time::Instant::now (1 samples, 0.08%)</title><rect x="95.4014%" y="101" width="0.0779%" height="15" fill="rgb(227,1,9)" fg:x="1224" fg:w="1"/><text x="95.6514%" y="111.50"></text></g><g><title>osprey.bundle`crossbeam_channel::flavors::list::Channel&lt;T&gt;::start_recv (2 samples, 0.16%)</title><rect x="95.4793%" y="117" width="0.1559%" height="15" fill="rgb(248,47,43)" fg:x="1225" fg:w="2"/><text x="95.7293%" y="127.50"></text></g><g><title>libsystem_c.dylib`clock_gettime_nsec_np (1 samples, 0.08%)</title><rect x="95.6352%" y="85" width="0.0779%" height="15" fill="rgb(221,10,30)" fg:x="1227" fg:w="1"/><text x="95.8852%" y="95.50"></text></g><g><title>osprey.bundle`crossbeam_channel::channel::Receiver&lt;T&gt;::recv_timeout (1,182 samples, 92.13%)</title><rect x="4.2868%" y="133" width="92.1278%" height="15" fill="rgb(210,229,1)" fg:x="55" fg:w="1182"/><text x="4.5368%" y="143.50">osprey.bundle`crossbeam_channel::channel::Receiver&lt;T&gt;::recv_timeout</text></g><g><title>osprey.bundle`std::sys::pal::unix::time::Timespec::now (10 samples, 0.78%)</title><rect x="95.6352%" y="117" width="0.7794%" height="15" fill="rgb(222,148,37)" fg:x="1227" fg:w="10"/><text x="95.8852%" y="127.50"></text></g><g><title>libsystem_c.dylib`clock_gettime (10 samples, 0.78%)</title><rect x="95.6352%" y="101" width="0.7794%" height="15" fill="rgb(234,67,33)" fg:x="1227" fg:w="10"/><text x="95.8852%" y="111.50"></text></g><g><title>libsystem_kernel.dylib`mach_absolute_time (9 samples, 0.70%)</title><rect x="95.7132%" y="85" width="0.7015%" height="15" fill="rgb(247,98,35)" fg:x="1228" fg:w="9"/><text x="95.9632%" y="95.50"></text></g><g><title>libruby.3.4.dylib`rb_nogvl (1,224 samples, 95.40%)</title><rect x="1.0912%" y="165" width="95.4014%" height="15" fill="rgb(247,138,52)" fg:x="14" fg:w="1224"/><text x="1.3412%" y="175.50">libruby.3.4.dylib`rb_nogvl</text></g><g><title>osprey.bundle`osprey::gather_requests_no_gvl (1,189 samples, 92.67%)</title><rect x="3.8192%" y="149" width="92.6734%" height="15" fill="rgb(213,79,30)" fg:x="49" fg:w="1189"/><text x="4.0692%" y="159.50">osprey.bundle`osprey::gather_requests_no_gvl</text></g><g><title>osprey.bundle`crossbeam_channel::channel::Receiver&lt;T&gt;::try_recv (1 samples, 0.08%)</title><rect x="96.4147%" y="133" width="0.0779%" height="15" fill="rgb(246,177,23)" fg:x="1237" fg:w="1"/><text x="96.6647%" y="143.50"></text></g><g><title>libsystem_kernel.dylib`sigprocmask (22 samples, 1.71%)</title><rect x="96.4926%" y="165" width="1.7147%" height="15" fill="rgb(230,62,27)" fg:x="1238" fg:w="22"/><text x="96.7426%" y="175.50"></text></g><g><title>libsystem_malloc.dylib`DYLD-STUB$$_platform_memset (3 samples, 0.23%)</title><rect x="98.2073%" y="165" width="0.2338%" height="15" fill="rgb(216,154,8)" fg:x="1260" fg:w="3"/><text x="98.4573%" y="175.50"></text></g><g><title>libsystem_malloc.dylib`small_size (2 samples, 0.16%)</title><rect x="98.4412%" y="149" width="0.1559%" height="15" fill="rgb(244,35,45)" fg:x="1263" fg:w="2"/><text x="98.6912%" y="159.50"></text></g><g><title>libsystem_malloc.dylib`find_zone_and_free (5 samples, 0.39%)</title><rect x="98.4412%" y="165" width="0.3897%" height="15" fill="rgb(251,115,12)" fg:x="1263" fg:w="5"/><text x="98.6912%" y="175.50"></text></g><g><title>libsystem_malloc.dylib`szone_size (3 samples, 0.23%)</title><rect x="98.5970%" y="149" width="0.2338%" height="15" fill="rgb(240,54,50)" fg:x="1265" fg:w="3"/><text x="98.8470%" y="159.50"></text></g><g><title>libsystem_malloc.dylib`tiny_size (3 samples, 0.23%)</title><rect x="98.5970%" y="133" width="0.2338%" height="15" fill="rgb(233,84,52)" fg:x="1265" fg:w="3"/><text x="98.8470%" y="143.50"></text></g><g><title>libsystem_malloc.dylib`free_small (1 samples, 0.08%)</title><rect x="98.8309%" y="165" width="0.0779%" height="15" fill="rgb(207,117,47)" fg:x="1268" fg:w="1"/><text x="99.0809%" y="175.50"></text></g><g><title>libsystem_malloc.dylib`free_tiny (3 samples, 0.23%)</title><rect x="98.9088%" y="165" width="0.2338%" height="15" fill="rgb(249,43,39)" fg:x="1269" fg:w="3"/><text x="99.1588%" y="175.50"></text></g><g><title>libsystem_malloc.dylib`nanov2_size (4 samples, 0.31%)</title><rect x="99.1426%" y="165" width="0.3118%" height="15" fill="rgb(209,38,44)" fg:x="1272" fg:w="4"/><text x="99.3926%" y="175.50"></text></g><g><title>libsystem_malloc.dylib`szone_size (1 samples, 0.08%)</title><rect x="99.4544%" y="165" width="0.0779%" height="15" fill="rgb(236,212,23)" fg:x="1276" fg:w="1"/><text x="99.7044%" y="175.50"></text></g><g><title>libsystem_platform.dylib`DYLD-STUB$$sigprocmask (1 samples, 0.08%)</title><rect x="99.5323%" y="165" width="0.0779%" height="15" fill="rgb(242,79,21)" fg:x="1277" fg:w="1"/><text x="99.7823%" y="175.50"></text></g><g><title>all (1,283 samples, 100%)</title><rect x="0.0000%" y="341" width="100.0000%" height="15" fill="rgb(211,96,35)" fg:x="0" fg:w="1283"/><text x="0.2500%" y="351.50"></text></g><g><title>libruby.3.4.dylib`fiber_entry (1,283 samples, 100.00%)</title><rect x="0.0000%" y="325" width="100.0000%" height="15" fill="rgb(253,215,40)" fg:x="0" fg:w="1283"/><text x="0.2500%" y="335.50">libruby.3.4.dylib`fiber_entry</text></g><g><title>libruby.3.4.dylib`fiber_pool_expand (1,283 samples, 100.00%)</title><rect x="0.0000%" y="309" width="100.0000%" height="15" fill="rgb(211,81,21)" fg:x="0" fg:w="1283"/><text x="0.2500%" y="319.50">libruby.3.4.dylib`fiber_pool_expand</text></g><g><title>libruby.3.4.dylib`rb_fiber_start (1,283 samples, 100.00%)</title><rect x="0.0000%" y="293" width="100.0000%" height="15" fill="rgb(208,190,38)" fg:x="0" fg:w="1283"/><text x="0.2500%" y="303.50">libruby.3.4.dylib`rb_fiber_start</text></g><g><title>libruby.3.4.dylib`vm_invoke_proc (1,283 samples, 100.00%)</title><rect x="0.0000%" y="277" width="100.0000%" height="15" fill="rgb(235,213,38)" fg:x="0" fg:w="1283"/><text x="0.2500%" y="287.50">libruby.3.4.dylib`vm_invoke_proc</text></g><g><title>libruby.3.4.dylib`rb_vm_exec (1,283 samples, 100.00%)</title><rect x="0.0000%" y="261" width="100.0000%" height="15" fill="rgb(237,122,38)" fg:x="0" fg:w="1283"/><text x="0.2500%" y="271.50">libruby.3.4.dylib`rb_vm_exec</text></g><g><title>libruby.3.4.dylib`vm_exec_core (1,283 samples, 100.00%)</title><rect x="0.0000%" y="245" width="100.0000%" height="15" fill="rgb(244,218,35)" fg:x="0" fg:w="1283"/><text x="0.2500%" y="255.50">libruby.3.4.dylib`vm_exec_core</text></g><g><title>libruby.3.4.dylib`vm_invoke_ifunc_block (1,283 samples, 100.00%)</title><rect x="0.0000%" y="229" width="100.0000%" height="15" fill="rgb(240,68,47)" fg:x="0" fg:w="1283"/><text x="0.2500%" y="239.50">libruby.3.4.dylib`vm_invoke_ifunc_block</text></g><g><title>libruby.3.4.dylib`vm_yield_with_cfunc (1,283 samples, 100.00%)</title><rect x="0.0000%" y="213" width="100.0000%" height="15" fill="rgb(210,16,53)" fg:x="0" fg:w="1283"/><text x="0.2500%" y="223.50">libruby.3.4.dylib`vm_yield_with_cfunc</text></g><g><title>osprey.bundle`magnus::block::_&lt;impl magnus::api::Ruby&gt;::proc_from_fn::call (1,283 samples, 100.00%)</title><rect x="0.0000%" y="197" width="100.0000%" height="15" fill="rgb(235,124,12)" fg:x="0" fg:w="1283"/><text x="0.2500%" y="207.50">osprey.bundle`magnus::block::_&lt;impl magnus::api::Ruby&gt;::proc_from_fn::call</text></g><g><title>osprey.bundle`core::ops::function::impls::_&lt;impl core::ops::function::FnOnce&lt;A&gt; for &amp;mut F&gt;::call_once (1,274 samples, 99.30%)</title><rect x="0.7015%" y="181" width="99.2985%" height="15" fill="rgb(224,169,11)" fg:x="9" fg:w="1274"/><text x="0.9515%" y="191.50">osprey.bundle`core::ops::function::impls::_&lt;impl core::ops::function::FnOnce&lt;A&gt; for &amp;mut F&gt;::call_once</text></g><g><title>libsystem_platform.dylib`_platform_memset (5 samples, 0.39%)</title><rect x="99.6103%" y="165" width="0.3897%" height="15" fill="rgb(250,166,2)" fg:x="1278" fg:w="5"/><text x="99.8603%" y="175.50"></text></g></svg></svg>
Binary file
@@ -0,0 +1,8 @@
1
+ apply_osx_fork_safety_patch = [
2
+ ENV["OBJC_DISABLE_INITIALIZE_FORK_SAFETY"].nil?,
3
+ RUBY_PLATFORM =~ /darwin/ ,
4
+ !ENV.key?('OSPREY_DISABLE_AUTO_DISABLE_OBJ_FORK_SAFETY'),
5
+ $PROGRAM_NAME =~ %r{osprey$}
6
+ ].all?
7
+
8
+ exec(ENV.to_h.merge("OBJC_DISABLE_INITIALIZE_FORK_SAFETY" => "YES"), *[$PROGRAM_NAME] + ARGV) if apply_osx_fork_safety_patch
@@ -0,0 +1,22 @@
1
+ return unless defined?(::Rackup::Handler)
2
+
3
+ module Rack
4
+ module Handler
5
+ module Osprey
6
+ def self.run(app, options = {})
7
+ ::Osprey.start(
8
+ host: options.fetch(:host, "127.0.0.1"),
9
+ port: options.fetch(:port, 3001),
10
+ workers: options.fetch(:workers, 1),
11
+ threads: options.fetch(:threads, 1),
12
+ http_port: options.fetch(:http_port, 3000),
13
+ cert_path: "/Users/pico/Development/osprey/server.cert",
14
+ key_path: "/Users/pico/Development/osprey/server.key",
15
+ app: app
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
21
+ ::Rackup::Handler.register("osprey", Rack::Handler::Osprey)
22
+ ::Rackup::Handler.register("Osprey", Rack::Handler::Osprey)
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Osprey
4
+ VERSION = "0.1.0"
5
+ end
data/lib/osprey.rb ADDED
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "async"
4
+ require_relative "osprey/version"
5
+ require_relative "osprey/osprey"
6
+ require_relative "osprey/patches"
7
+ require_relative "osprey/rack/handler/osprey"
8
+ require "debug"
9
+
10
+ module Osprey
11
+ class Error < StandardError; end
12
+
13
+ MAX_CONCURRENT_FIBERS = 1000
14
+
15
+ def self.call(...)
16
+ @handler.call(to_env(...))
17
+ end
18
+
19
+ def self.to_env(
20
+ (query_string, remote_addr, path_info), script_name, method, host, scheme, version,
21
+ protocol, port, fd, headers, hijack_proc
22
+ )
23
+ env = {
24
+ "SERVER_SOFTWARE" => "Osprey",
25
+ "SCRIPT_NAME" => script_name,
26
+ "REQUEST_METHOD" => method,
27
+ "PATH_INFO" => path_info,
28
+ "QUERY_STRING" => query_string,
29
+ "REMOTE_ADDR" => remote_addr,
30
+ "SERVER_NAME" => host,
31
+ "SERVER_PORT" => port,
32
+ "SERVER_PROTOCOL" => protocol,
33
+ "HTTP_HOST" => host,
34
+ "HTTP_VERSION" => version,
35
+ "rack.url_scheme" => scheme,
36
+ "rack.hijack_enabled?" => true,
37
+ "rack.hijack" => hijack_proc,
38
+ "rack.protocol" => protocol,
39
+ "rack.input" => fd.positive? ? IO.new(fd, "rb") : StringIO.new,
40
+ "rack.errors" => $stderr,
41
+ "rack.multipart.buffer_size" => 16_384,
42
+ }.merge(
43
+ headers.transform_keys do |k|
44
+ case k
45
+ when "content-length" then "CONTENT_LENGTH"
46
+ when "content-type" then "CONTENT_TYPE"
47
+ when "authorization" then "AUTH_TYPE"
48
+ else "HTTP_#{k.upcase.tr("-", "_")}"
49
+ end
50
+ end
51
+ )
52
+ end
53
+ end
data/server.cert ADDED
Binary file
data/server.key ADDED
Binary file
@@ -0,0 +1,4 @@
1
+ module Osprey
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end