rian 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
package/index.d.ts CHANGED
@@ -1,8 +1,4 @@
1
1
  import { Traceparent } from 'tctx';
2
- import { Scope as Scope$1 } from 'rian';
3
-
4
- declare type MeasureFn = ((...args: [...args: any[]]) => any) | ((...args: [...args: any[], scope: Scope$1]) => any);
5
- declare type RealMeasureFnParams<T extends unknown[]> = T extends [] ? [] : T extends [...rest: infer U, scope: Scope$1] ? U : T;
6
2
 
7
3
  /**
8
4
  * Spans are units within a distributed trace. Spans encapsulate mainly 3 pieces of information, a
@@ -96,30 +92,6 @@ interface Scope {
96
92
  * Forks the span into a new child span.
97
93
  */
98
94
  fork(name: string): CallableScope;
99
- /**
100
- * With a passed function — will start a span, and run the function, when the function finishes
101
- * the span finishes.
102
- *
103
- * The measure method will return whatever the function is, so if it's a promise, it returns a
104
- * promise and so on. Any error is caught and re thrown, and automatically tracked in the
105
- * context under the `error` property.
106
- *
107
- * All promises are tracked, and awaited on a `tracer.end`.
108
- *
109
- * @example
110
- *
111
- * ```text
112
- * const data = await scope.measure('name', get_data, 'user_id_123');
113
- * ^ ^ ^ ^
114
- * | | | |
115
- * | | | the first argument to get_data
116
- * | | function to be called
117
- * | the name of the sub scope
118
- * return value from get_data
119
- * ```
120
- */
121
- measure<Fn extends MeasureFn>(name: string, fn: Fn, // TODO: fn doesnt see scope correctly
122
- ...args: RealMeasureFnParams<Parameters<Fn>>): ReturnType<Fn>;
123
95
  /**
124
96
  * Allows the span's context to be set. Passing an object will be `Object.assign`ed into the
125
97
  * current context.
package/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  const package_json = require('rian/package.json');
4
4
  const tctx = require('tctx');
5
+ const rian = require('rian');
5
6
 
6
7
  function _interopNamespace(e) {
7
8
  if (e && e.__esModule) return e;
@@ -28,12 +29,11 @@ const set_error = (scope, error) => {
28
29
  error,
29
30
  });
30
31
  };
31
- const measure = (fn, // TODO: fn doesnt see scope correctly
32
- scope, promises, ...args) => {
32
+ const measureFn = (scope, fn, ...args) => {
33
33
  try {
34
34
  var r = fn(...args, scope), is_promise = r instanceof Promise;
35
- if (is_promise)
36
- promises.push(r
35
+ if (is_promise && rian.PROMISES.has(scope))
36
+ rian.ADD_PROMISE(scope, r
37
37
  .catch((e) => void set_error(scope, e))
38
38
  .finally(() => scope.end()));
39
39
  return r;
@@ -47,8 +47,44 @@ scope, promises, ...args) => {
47
47
  scope.end();
48
48
  }
49
49
  };
50
+ /**
51
+ * With a passed function — will start a span, and run the function, when the function finishes
52
+ * the span finishes.
53
+ *
54
+ * The measure method will return whatever the function is, so if it's a promise, it returns a
55
+ * promise and so on. Any error is caught and re thrown, and automatically tracked in the
56
+ * context under the `error` property.
57
+ *
58
+ * All promises are tracked, and awaited on a `tracer.end`.
59
+ *
60
+ * @example
61
+ *
62
+ * ```text
63
+ * const data = await measure(scope, get_data, 'user_id_123');
64
+ * ^ ^ ^
65
+ * | | |
66
+ * | | the first argument to get_data
67
+ * | function to be called
68
+ * return value from get_data
69
+ * ```
70
+ */
71
+ const measure = (scope, fn, // TODO: fn doesnt see scope correctly
72
+ ...args) => measureFn(scope, fn, ...args);
50
73
 
51
74
  // ==> impl
75
+ /**
76
+ * @internal
77
+ */
78
+ const PROMISES = new WeakMap();
79
+ /**
80
+ * @internal
81
+ */
82
+ const ADD_PROMISE = (scope, promise) => {
83
+ if (PROMISES.has(scope))
84
+ PROMISES.get(scope).push(promise);
85
+ else
86
+ PROMISES.set(scope, [promise]);
87
+ };
52
88
  /**
53
89
  * The default sampler;
54
90
  *
@@ -70,7 +106,6 @@ const sdk_object = {
70
106
  };
71
107
  const create = (name, options) => {
72
108
  const spans = new Set();
73
- const promises = [];
74
109
  const sampler = options.sampler || defaultSampler;
75
110
  const sampler_callable = typeof sampler !== 'boolean';
76
111
  const span = (name, parent) => {
@@ -90,10 +125,9 @@ const create = (name, options) => {
90
125
  };
91
126
  if (should_sample)
92
127
  spans.add(span_obj);
93
- const $ = (cb) => measure(cb, $, promises);
128
+ const $ = (cb) => measure($, cb);
94
129
  $.traceparent = id;
95
130
  $.fork = (name) => span(name, id);
96
- $.measure = (name, cb, ...args) => measure(cb, span(name, id), promises, ...args);
97
131
  $.set_context = (ctx) => {
98
132
  if (typeof ctx === 'function')
99
133
  return void (span_obj.context = ctx(span_obj.context));
@@ -119,8 +153,8 @@ const create = (name, options) => {
119
153
  const endRoot = root.end.bind(root);
120
154
  root.end = async () => {
121
155
  endRoot();
122
- if (promises.length)
123
- await Promise.all(promises);
156
+ if (PROMISES.has(root))
157
+ await Promise.all(PROMISES.get(root));
124
158
  return options.exporter(spans, {
125
159
  ...(options.context || {}),
126
160
  ...sdk_object,
@@ -129,4 +163,6 @@ const create = (name, options) => {
129
163
  return root;
130
164
  };
131
165
 
166
+ exports.ADD_PROMISE = ADD_PROMISE;
167
+ exports.PROMISES = PROMISES;
132
168
  exports.create = create;
package/index.mjs CHANGED
@@ -1,17 +1,17 @@
1
1
  import { name, version } from 'rian/package.json';
2
2
  import * as tctx from 'tctx';
3
+ import { PROMISES as PROMISES$1, ADD_PROMISE as ADD_PROMISE$1 } from 'rian';
3
4
 
4
5
  const set_error = (scope, error) => {
5
6
  scope.set_context({
6
7
  error,
7
8
  });
8
9
  };
9
- const measure = (fn, // TODO: fn doesnt see scope correctly
10
- scope, promises, ...args) => {
10
+ const measureFn = (scope, fn, ...args) => {
11
11
  try {
12
12
  var r = fn(...args, scope), is_promise = r instanceof Promise;
13
- if (is_promise)
14
- promises.push(r
13
+ if (is_promise && PROMISES$1.has(scope))
14
+ ADD_PROMISE$1(scope, r
15
15
  .catch((e) => void set_error(scope, e))
16
16
  .finally(() => scope.end()));
17
17
  return r;
@@ -25,8 +25,44 @@ scope, promises, ...args) => {
25
25
  scope.end();
26
26
  }
27
27
  };
28
+ /**
29
+ * With a passed function — will start a span, and run the function, when the function finishes
30
+ * the span finishes.
31
+ *
32
+ * The measure method will return whatever the function is, so if it's a promise, it returns a
33
+ * promise and so on. Any error is caught and re thrown, and automatically tracked in the
34
+ * context under the `error` property.
35
+ *
36
+ * All promises are tracked, and awaited on a `tracer.end`.
37
+ *
38
+ * @example
39
+ *
40
+ * ```text
41
+ * const data = await measure(scope, get_data, 'user_id_123');
42
+ * ^ ^ ^
43
+ * | | |
44
+ * | | the first argument to get_data
45
+ * | function to be called
46
+ * return value from get_data
47
+ * ```
48
+ */
49
+ const measure = (scope, fn, // TODO: fn doesnt see scope correctly
50
+ ...args) => measureFn(scope, fn, ...args);
28
51
 
29
52
  // ==> impl
53
+ /**
54
+ * @internal
55
+ */
56
+ const PROMISES = new WeakMap();
57
+ /**
58
+ * @internal
59
+ */
60
+ const ADD_PROMISE = (scope, promise) => {
61
+ if (PROMISES.has(scope))
62
+ PROMISES.get(scope).push(promise);
63
+ else
64
+ PROMISES.set(scope, [promise]);
65
+ };
30
66
  /**
31
67
  * The default sampler;
32
68
  *
@@ -48,7 +84,6 @@ const sdk_object = {
48
84
  };
49
85
  const create = (name, options) => {
50
86
  const spans = new Set();
51
- const promises = [];
52
87
  const sampler = options.sampler || defaultSampler;
53
88
  const sampler_callable = typeof sampler !== 'boolean';
54
89
  const span = (name, parent) => {
@@ -68,10 +103,9 @@ const create = (name, options) => {
68
103
  };
69
104
  if (should_sample)
70
105
  spans.add(span_obj);
71
- const $ = (cb) => measure(cb, $, promises);
106
+ const $ = (cb) => measure($, cb);
72
107
  $.traceparent = id;
73
108
  $.fork = (name) => span(name, id);
74
- $.measure = (name, cb, ...args) => measure(cb, span(name, id), promises, ...args);
75
109
  $.set_context = (ctx) => {
76
110
  if (typeof ctx === 'function')
77
111
  return void (span_obj.context = ctx(span_obj.context));
@@ -97,8 +131,8 @@ const create = (name, options) => {
97
131
  const endRoot = root.end.bind(root);
98
132
  root.end = async () => {
99
133
  endRoot();
100
- if (promises.length)
101
- await Promise.all(promises);
134
+ if (PROMISES.has(root))
135
+ await Promise.all(PROMISES.get(root));
102
136
  return options.exporter(spans, {
103
137
  ...(options.context || {}),
104
138
  ...sdk_object,
@@ -107,4 +141,4 @@ const create = (name, options) => {
107
141
  return root;
108
142
  };
109
143
 
110
- export { create };
144
+ export { ADD_PROMISE, PROMISES, create };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rian",
3
- "version": "0.0.5",
3
+ "version": "0.1.0",
4
4
  "description": "Effective tracing for the edge and origins",
5
5
  "keywords": [
6
6
  "opentelemetry",
@@ -37,6 +37,10 @@
37
37
  "import": "./exporter.zipkin.mjs",
38
38
  "require": "./exporter.zipkin.js"
39
39
  },
40
+ "./utils": {
41
+ "import": "./utils.mjs",
42
+ "require": "./utils.js"
43
+ },
40
44
  "./package.json": "./package.json"
41
45
  },
42
46
  "main": "./index.js",
package/utils.d.ts ADDED
@@ -0,0 +1,43 @@
1
+ import { Scope } from 'rian';
2
+
3
+ declare type MeasureFn = ((...args: [...args: any[]]) => any) | ((...args: [...args: any[], scope: Scope]) => any);
4
+ declare type RealMeasureFnParams<T extends unknown[]> = T extends [] ? [] : T extends [...rest: infer U, scope: Scope] ? U : T;
5
+ /**
6
+ * With a passed function — will start a span, and run the function, when the function finishes
7
+ * the span finishes.
8
+ *
9
+ * The measure method will return whatever the function is, so if it's a promise, it returns a
10
+ * promise and so on. Any error is caught and re thrown, and automatically tracked in the
11
+ * context under the `error` property.
12
+ *
13
+ * All promises are tracked, and awaited on a `tracer.end`.
14
+ *
15
+ * @example
16
+ *
17
+ * ```text
18
+ * const data = await measure(scope, get_data, 'user_id_123');
19
+ * ^ ^ ^
20
+ * | | |
21
+ * | | the first argument to get_data
22
+ * | function to be called
23
+ * return value from get_data
24
+ * ```
25
+ */
26
+ declare const measure: <Fn extends MeasureFn>(scope: Scope, fn: Fn, ...args: RealMeasureFnParams<Parameters<Fn>>) => ReturnType<Fn>;
27
+ /**
28
+ * Wraps any function with a measured scoped function. Useful for when defer function execution
29
+ * till a later time.
30
+ *
31
+ * @example
32
+ *
33
+ * ```js
34
+ * const wrapped = wrap(scope, my_function);
35
+ *
36
+ * // ... lots of things, where the access to `scope` is lost.
37
+ *
38
+ * wrapped();
39
+ * ```
40
+ */
41
+ declare const wrap: <Fn extends MeasureFn>(scope: Scope, fn: Fn) => Fn;
42
+
43
+ export { MeasureFn, measure, wrap };
package/utils.js ADDED
@@ -0,0 +1,70 @@
1
+ 'use strict';
2
+
3
+ const rian = require('rian');
4
+
5
+ const set_error = (scope, error) => {
6
+ scope.set_context({
7
+ error,
8
+ });
9
+ };
10
+ const measureFn = (scope, fn, ...args) => {
11
+ try {
12
+ var r = fn(...args, scope), is_promise = r instanceof Promise;
13
+ if (is_promise && rian.PROMISES.has(scope))
14
+ rian.ADD_PROMISE(scope, r
15
+ .catch((e) => void set_error(scope, e))
16
+ .finally(() => scope.end()));
17
+ return r;
18
+ }
19
+ catch (e) {
20
+ set_error(scope, e);
21
+ throw e;
22
+ }
23
+ finally {
24
+ if (is_promise !== true)
25
+ scope.end();
26
+ }
27
+ };
28
+ /**
29
+ * With a passed function — will start a span, and run the function, when the function finishes
30
+ * the span finishes.
31
+ *
32
+ * The measure method will return whatever the function is, so if it's a promise, it returns a
33
+ * promise and so on. Any error is caught and re thrown, and automatically tracked in the
34
+ * context under the `error` property.
35
+ *
36
+ * All promises are tracked, and awaited on a `tracer.end`.
37
+ *
38
+ * @example
39
+ *
40
+ * ```text
41
+ * const data = await measure(scope, get_data, 'user_id_123');
42
+ * ^ ^ ^
43
+ * | | |
44
+ * | | the first argument to get_data
45
+ * | function to be called
46
+ * return value from get_data
47
+ * ```
48
+ */
49
+ const measure = (scope, fn, // TODO: fn doesnt see scope correctly
50
+ ...args) => measureFn(scope, fn, ...args);
51
+ /**
52
+ * Wraps any function with a measured scoped function. Useful for when defer function execution
53
+ * till a later time.
54
+ *
55
+ * @example
56
+ *
57
+ * ```js
58
+ * const wrapped = wrap(scope, my_function);
59
+ *
60
+ * // ... lots of things, where the access to `scope` is lost.
61
+ *
62
+ * wrapped();
63
+ * ```
64
+ */
65
+ const wrap = (scope, fn) => function () {
66
+ return measureFn(scope, fn, ...arguments);
67
+ };
68
+
69
+ exports.measure = measure;
70
+ exports.wrap = wrap;
package/utils.mjs ADDED
@@ -0,0 +1,67 @@
1
+ import { PROMISES, ADD_PROMISE } from 'rian';
2
+
3
+ const set_error = (scope, error) => {
4
+ scope.set_context({
5
+ error,
6
+ });
7
+ };
8
+ const measureFn = (scope, fn, ...args) => {
9
+ try {
10
+ var r = fn(...args, scope), is_promise = r instanceof Promise;
11
+ if (is_promise && PROMISES.has(scope))
12
+ ADD_PROMISE(scope, r
13
+ .catch((e) => void set_error(scope, e))
14
+ .finally(() => scope.end()));
15
+ return r;
16
+ }
17
+ catch (e) {
18
+ set_error(scope, e);
19
+ throw e;
20
+ }
21
+ finally {
22
+ if (is_promise !== true)
23
+ scope.end();
24
+ }
25
+ };
26
+ /**
27
+ * With a passed function — will start a span, and run the function, when the function finishes
28
+ * the span finishes.
29
+ *
30
+ * The measure method will return whatever the function is, so if it's a promise, it returns a
31
+ * promise and so on. Any error is caught and re thrown, and automatically tracked in the
32
+ * context under the `error` property.
33
+ *
34
+ * All promises are tracked, and awaited on a `tracer.end`.
35
+ *
36
+ * @example
37
+ *
38
+ * ```text
39
+ * const data = await measure(scope, get_data, 'user_id_123');
40
+ * ^ ^ ^
41
+ * | | |
42
+ * | | the first argument to get_data
43
+ * | function to be called
44
+ * return value from get_data
45
+ * ```
46
+ */
47
+ const measure = (scope, fn, // TODO: fn doesnt see scope correctly
48
+ ...args) => measureFn(scope, fn, ...args);
49
+ /**
50
+ * Wraps any function with a measured scoped function. Useful for when defer function execution
51
+ * till a later time.
52
+ *
53
+ * @example
54
+ *
55
+ * ```js
56
+ * const wrapped = wrap(scope, my_function);
57
+ *
58
+ * // ... lots of things, where the access to `scope` is lost.
59
+ *
60
+ * wrapped();
61
+ * ```
62
+ */
63
+ const wrap = (scope, fn) => function () {
64
+ return measureFn(scope, fn, ...arguments);
65
+ };
66
+
67
+ export { measure, wrap };