@cognelis/signoz-cli 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/install.js +27 -11
  2. package/package.json +1 -1
package/install.js CHANGED
@@ -8,7 +8,8 @@ const pkg = require('./package.json');
8
8
 
9
9
  const MAX_BINARY_BYTES = 64 * 1024 * 1024;
10
10
  const MAX_CHECKSUM_BYTES = 64 * 1024;
11
- const DOWNLOAD_TIMEOUT_MS = 30_000;
11
+ const DOWNLOAD_TIMEOUT_MS = 10 * 60_000;
12
+ const IDLE_TIMEOUT_MS = 30_000;
12
13
  const inFlight = new Map();
13
14
 
14
15
  function assetName(platform = process.platform, arch = process.arch) {
@@ -46,6 +47,7 @@ function checksumFor(text, asset) {
46
47
  function download(address, maxBytes, options = {}) {
47
48
  const request = options.request || https.get;
48
49
  const timeoutMs = options.timeoutMs || DOWNLOAD_TIMEOUT_MS;
50
+ const idleTimeoutMs = options.idleTimeoutMs || IDLE_TIMEOUT_MS;
49
51
  const started = Date.now();
50
52
  function get(url, redirects) {
51
53
  return new Promise((resolve, reject) => {
@@ -58,10 +60,22 @@ function download(address, maxBytes, options = {}) {
58
60
  const remaining = timeoutMs - (Date.now() - started);
59
61
  if (remaining <= 0) { reject(new Error('Binary download timed out.')); return; }
60
62
  let timer;
63
+ let idle;
64
+ let done = false;
65
+ const settle = () => { done = true; clearTimeout(timer); clearTimeout(idle); };
66
+ // Reject before destroying so a later "interrupted" event cannot replace the reason.
67
+ const fail = message => { settle(); reject(new Error(message)); req.destroy(); };
68
+ // A slow link may take minutes; only a transfer that stops sending data is abandoned.
69
+ const touch = () => {
70
+ if (done) return;
71
+ clearTimeout(idle);
72
+ idle = setTimeout(() => fail(`Binary download stalled: no data for ${idleTimeoutMs / 1000} seconds.`), idleTimeoutMs);
73
+ };
61
74
  const req = request(parsed, {method: options.method || 'GET', headers: {'User-Agent': 'signoz-cli-npm-installer'}}, res => {
75
+ touch();
62
76
  if ([301, 302, 303, 307, 308].includes(res.statusCode) && res.headers.location) {
63
77
  res.destroy();
64
- clearTimeout(timer);
78
+ settle();
65
79
  try {
66
80
  resolve(get(new URL(res.headers.location, parsed).href, redirects + 1));
67
81
  } catch { reject(new Error('Invalid release download redirect.')); }
@@ -69,39 +83,41 @@ function download(address, maxBytes, options = {}) {
69
83
  }
70
84
  if (res.statusCode !== 200) {
71
85
  res.destroy();
72
- clearTimeout(timer);
86
+ settle();
73
87
  reject(new Error(`Release download returned HTTP ${res.statusCode} from ${parsed.hostname}.`));
74
88
  return;
75
89
  }
76
90
  const declared = Number(res.headers['content-length']);
77
91
  if (options.requireContentLength && (!Number.isFinite(declared) || declared <= 0)) {
78
92
  res.destroy();
79
- clearTimeout(timer);
93
+ settle();
80
94
  reject(new Error('Release asset has no valid content length.'));
81
95
  return;
82
96
  }
83
97
  if (Number.isFinite(declared) && declared > maxBytes) {
84
98
  res.destroy();
85
- clearTimeout(timer);
99
+ settle();
86
100
  reject(new Error(`Release download exceeds ${maxBytes} bytes.`));
87
101
  return;
88
102
  }
89
103
  const chunks = [];
90
104
  let size = 0;
91
105
  res.on('data', chunk => {
106
+ touch();
92
107
  size += chunk.length;
93
108
  if (size > maxBytes) {
94
- clearTimeout(timer);
109
+ settle();
95
110
  res.destroy();
96
111
  reject(new Error(`Release download exceeds ${maxBytes} bytes.`));
97
112
  } else chunks.push(chunk);
98
113
  });
99
- res.on('end', () => { clearTimeout(timer); resolve(Buffer.concat(chunks)); });
100
- res.on('error', error => { clearTimeout(timer); reject(error); });
101
- res.on('aborted', () => { clearTimeout(timer); reject(new Error('Release download was interrupted.')); });
114
+ res.on('end', () => { settle(); resolve(Buffer.concat(chunks)); });
115
+ res.on('error', error => { settle(); reject(error); });
116
+ res.on('aborted', () => { settle(); reject(new Error('Release download was interrupted.')); });
102
117
  });
103
- req.on('error', error => { clearTimeout(timer); reject(error); });
104
- timer = setTimeout(() => req.destroy(new Error('Binary download timed out.')), remaining);
118
+ req.on('error', error => { settle(); reject(error); });
119
+ timer = setTimeout(() => fail('Binary download timed out.'), remaining);
120
+ touch();
105
121
  });
106
122
  }
107
123
  return get(address, 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cognelis/signoz-cli",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Read-only SigNoz queries, diagnostics, profiles, and shell completion for terminals and coding agents.",
5
5
  "homepage": "https://github.com/cognelis/signoz-cli#readme",
6
6
  "repository": {