helia-coord 1.5.7 → 1.5.9

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 (45) hide show
  1. package/examples/create-helia-node.js +3 -1
  2. package/examples/memory-usage/README.md +12 -0
  3. package/examples/memory-usage/create-helia-node.js +154 -0
  4. package/examples/memory-usage/json-to-csv.js +28 -0
  5. package/examples/memory-usage/memory-log-example.json +3 -0
  6. package/examples/memory-usage/memory-log.json +3 -0
  7. package/examples/memory-usage/start-node.js +57 -0
  8. package/index.js +1 -1
  9. package/lib/adapters/ipfs-adapter.js +3 -3
  10. package/lib/controllers/timer-controller.js +3 -3
  11. package/lib/use-cases/pubsub-use-cases.js +2 -2
  12. package/lib/use-cases/this-node-use-cases.js +1 -0
  13. package/mem-test/README.md +12 -0
  14. package/mem-test/create-helia-node.js +154 -0
  15. package/mem-test/json-to-csv.js +28 -0
  16. package/mem-test/memory-log.json +3 -0
  17. package/mem-test/snapshots/v1.5.8/00-v1.5.8/memory-log.xlsx +0 -0
  18. package/mem-test/snapshots/v1.5.8/01-baseline/01-baseline.xlsx +0 -0
  19. package/mem-test/snapshots/v1.5.8/02-pubsub/02-pubsub.xlsx +0 -0
  20. package/mem-test/snapshots/v1.5.8/02-pubsub/memory-log.json +324 -0
  21. package/mem-test/snapshots/v1.5.8/03-init-connections-1/memory-log.csv +61 -0
  22. package/mem-test/snapshots/v1.5.8/03-init-connections-1/memory-log.json +604 -0
  23. package/mem-test/snapshots/v1.5.8/03-init-connections-1/memory-log.xlsx +0 -0
  24. package/mem-test/snapshots/v1.5.8/03-init-connections-2/README.md +8 -0
  25. package/mem-test/snapshots/v1.5.8/03-init-connections-2/memory-log.csv +55 -0
  26. package/mem-test/snapshots/v1.5.8/03-init-connections-2/memory-log.json +544 -0
  27. package/mem-test/snapshots/v1.5.8/03-init-connections-2/memory-log.xlsx +0 -0
  28. package/mem-test/snapshots/v1.5.8/04-relay-reconnect-1/README.md +4 -0
  29. package/mem-test/snapshots/v1.5.8/04-relay-reconnect-1/memory-log.csv +77 -0
  30. package/mem-test/snapshots/v1.5.8/04-relay-reconnect-1/memory-log.json +764 -0
  31. package/mem-test/snapshots/v1.5.8/04-relay-reconnect-1/memory-log.xlsx +0 -0
  32. package/mem-test/snapshots/v1.5.8/04-relay-reconnect-2/README.md +4 -0
  33. package/mem-test/snapshots/v1.5.8/04-relay-reconnect-2/memory-log.csv +61 -0
  34. package/mem-test/snapshots/v1.5.8/04-relay-reconnect-2/memory-log.json +604 -0
  35. package/mem-test/snapshots/v1.5.8/04-relay-reconnect-2/memory-log.xlsx +0 -0
  36. package/mem-test/snapshots/v1.5.8/05-peer-reconnect-1/README.md +5 -0
  37. package/mem-test/snapshots/v1.5.8/05-peer-reconnect-1/memory-log.csv +493 -0
  38. package/mem-test/snapshots/v1.5.8/05-peer-reconnect-1/memory-log.json +4924 -0
  39. package/mem-test/snapshots/v1.5.8/05-peer-reconnect-1/memory-log.xlsx +0 -0
  40. package/mem-test/snapshots/v1.5.8/05-peer-reconnect-2/README.md +5 -0
  41. package/mem-test/snapshots/v1.5.8/05-peer-reconnect-2/memory-log.csv +64 -0
  42. package/mem-test/snapshots/v1.5.8/05-peer-reconnect-2/memory-log.json +634 -0
  43. package/mem-test/snapshots/v1.5.8/05-peer-reconnect-2/memory-log.xlsx +0 -0
  44. package/mem-test/start-node.js +57 -0
  45. package/package.json +12 -12
@@ -81,7 +81,7 @@ class CreateHeliaNode {
81
81
  // Configure services
82
82
  const services = {
83
83
  identify: identify(),
84
- pubsub: gossipsub({ allowPublishToZeroPeers: true })
84
+ pubsub: gossipsub({ allowPublishToZeroTopicPeers: true })
85
85
  }
86
86
 
87
87
  // libp2p is the networking layer that underpins Helia
@@ -143,6 +143,8 @@ class CreateHeliaNode {
143
143
 
144
144
  !fs.existsSync(`${IPFS_DIR}/datastore`) && fs.mkdirSync(`${IPFS_DIR}/datastore`)
145
145
 
146
+ // !fs.existsSync(`${IPFS_DIR}/datastore/peers`) && fs.mkdirSync(`${IPFS_DIR}/datastore/peers`)
147
+
146
148
  return true
147
149
  } catch (err) {
148
150
  console.error('Error in ensureBlocksDir(): ', err)
@@ -0,0 +1,12 @@
1
+ # Memory Usage
2
+
3
+ This is the same example app as the directory above, but it's been modified to take
4
+ periodic memory snapshots and write the memory usage to a JSON file. This is useful
5
+ for tracking potential memory leaks by monitoring memory usage over time.
6
+
7
+ ## Usage
8
+
9
+ Copy the `memory-log-example.json` to a new file called `memory-log.json`
10
+
11
+ Run this program with:
12
+ - `node start-node.js`
@@ -0,0 +1,154 @@
1
+ /*
2
+ This library creates a Helia IPFS node. This is done prior to attaching
3
+ helia-coord to the node.
4
+ This library is called by start-node.js.
5
+ */
6
+
7
+ // Global npm libraries
8
+ import { createHelia } from 'helia'
9
+ import fs from 'fs'
10
+ import { FsBlockstore } from 'blockstore-fs'
11
+ import { FsDatastore } from 'datastore-fs'
12
+ import { createLibp2p } from 'libp2p'
13
+ import { tcp } from '@libp2p/tcp'
14
+ import { noise } from '@chainsafe/libp2p-noise'
15
+ import { yamux } from '@chainsafe/libp2p-yamux'
16
+ // import { bootstrap } from '@libp2p/bootstrap'
17
+ // import { identifyService } from 'libp2p/identify'
18
+ import { identify } from '@libp2p/identify'
19
+ // import { circuitRelayTransport } from 'libp2p/circuit-relay'
20
+ import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'
21
+ import { gossipsub } from '@chainsafe/libp2p-gossipsub'
22
+ import { webSockets } from '@libp2p/websockets'
23
+ import { publicIpv4 } from 'public-ip'
24
+ import { multiaddr } from '@multiformats/multiaddr'
25
+ import { webRTC } from '@libp2p/webrtc'
26
+
27
+ const ROOT_DIR = './'
28
+ const IPFS_DIR = './.ipfsdata/ipfs'
29
+
30
+ class CreateHeliaNode {
31
+ constructor () {
32
+ this.publicIp = publicIpv4
33
+ }
34
+
35
+ // Start an IPFS node.
36
+ async start () {
37
+ try {
38
+ // Ensure the directory structure exists that is needed by the IPFS node to store data.
39
+ this.ensureBlocksDir()
40
+
41
+ // Create an IPFS node
42
+ const ipfs = await this.createNode()
43
+ // console.log('ipfs: ', ipfs)
44
+
45
+ this.id = ipfs.libp2p.peerId.toString()
46
+ console.log('IPFS ID: ', this.id)
47
+
48
+ // Attempt to guess our ip4 IP address.
49
+ const ip4 = await this.publicIp()
50
+ let detectedMultiaddr = `/ip4/${ip4}/tcp/4001/p2p/${this.id}`
51
+ detectedMultiaddr = multiaddr(detectedMultiaddr)
52
+
53
+ // Get the multiaddrs for the node.
54
+ const multiaddrs = ipfs.libp2p.getMultiaddrs()
55
+ multiaddrs.push(detectedMultiaddr)
56
+ console.log('Multiaddrs: ', multiaddrs)
57
+
58
+ this.multiaddrs = multiaddrs
59
+
60
+ // Signal that this adapter is ready.
61
+ this.isReady = true
62
+
63
+ this.ipfs = ipfs
64
+
65
+ return this.ipfs
66
+ } catch (err) {
67
+ console.error('Error in start()')
68
+
69
+ throw err
70
+ }
71
+ }
72
+
73
+ // This function creates an IPFS node using Helia.
74
+ // It returns the node as an object.
75
+ async createNode () {
76
+ try {
77
+ // Create block and data stores.
78
+ const blockstore = new FsBlockstore(`${IPFS_DIR}/blockstore`)
79
+ const datastore = new FsDatastore(`${IPFS_DIR}/datastore`)
80
+
81
+ // Configure services
82
+ const services = {
83
+ identify: identify(),
84
+ pubsub: gossipsub({ allowPublishToZeroPeers: true })
85
+ }
86
+
87
+ // libp2p is the networking layer that underpins Helia
88
+ const libp2p = await createLibp2p({
89
+ datastore,
90
+ addresses: {
91
+ listen: [
92
+ '/ip4/127.0.0.1/tcp/0',
93
+ '/ip4/0.0.0.0/tcp/4001',
94
+ '/ip4/0.0.0.0/tcp/4003/ws',
95
+ '/webrtc'
96
+ ]
97
+ },
98
+ transports: [
99
+ tcp(),
100
+ webSockets(),
101
+ circuitRelayTransport({ discoverRelays: 3 }),
102
+ webRTC()
103
+ ],
104
+ connectionEncryption: [
105
+ noise()
106
+ ],
107
+ streamMuxers: [
108
+ yamux()
109
+ ],
110
+ services
111
+ })
112
+
113
+ // create a Helia node
114
+ const helia = await createHelia({
115
+ blockstore,
116
+ datastore,
117
+ libp2p
118
+ })
119
+
120
+ return helia
121
+ } catch (err) {
122
+ console.error('Error creating Helia node: ', err)
123
+
124
+ throw err
125
+ }
126
+ }
127
+
128
+ async stop () {
129
+ await this.ipfs.stop()
130
+
131
+ return true
132
+ }
133
+
134
+ // Ensure that the directories exist to store blocks from the IPFS network.
135
+ // This function is called at startup, before the IPFS node is started.
136
+ ensureBlocksDir () {
137
+ try {
138
+ !fs.existsSync(`${ROOT_DIR}.ipfsdata`) && fs.mkdirSync(`${ROOT_DIR}.ipfsdata`)
139
+
140
+ !fs.existsSync(`${IPFS_DIR}`) && fs.mkdirSync(`${IPFS_DIR}`)
141
+
142
+ !fs.existsSync(`${IPFS_DIR}/blockstore`) && fs.mkdirSync(`${IPFS_DIR}/blockstore`)
143
+
144
+ !fs.existsSync(`${IPFS_DIR}/datastore`) && fs.mkdirSync(`${IPFS_DIR}/datastore`)
145
+
146
+ return true
147
+ } catch (err) {
148
+ console.error('Error in ensureBlocksDir(): ', err)
149
+ throw err
150
+ }
151
+ }
152
+ }
153
+
154
+ export default CreateHeliaNode
@@ -0,0 +1,28 @@
1
+ /*
2
+ This app converts the memory-log.json file to a CSV file that can be imported
3
+ into a spreadsheet for further analysis.
4
+ */
5
+
6
+ import fs from 'fs'
7
+
8
+ async function jsonToCsv () {
9
+ try {
10
+ const log = JSON.parse(fs.readFileSync('./memory-log.json'))
11
+ const memoryLogs = log.memoryLogs
12
+
13
+ let outStr = 'timestampIso,timestampJs,heapTotal (MB),heapUsed (MB),external (MB),arrayBuffers (MB),rss (MB)\n'
14
+
15
+ for (let i = 0; i < memoryLogs.length; i++) {
16
+ const thisLog = memoryLogs[i]
17
+
18
+ outStr += `${thisLog.timestampIso},${thisLog.timestampJs},${thisLog.heapTotal / 1000000},${thisLog.heapUsed / 1000000},${thisLog.external / 1000000},${thisLog.arrayBuffers / 1000000},${thisLog.rss / 1000000}\n`
19
+ }
20
+
21
+ await fs.writeFileSync('./memory-log.csv', outStr)
22
+ console.log('JSON memory log converted to CSV file.')
23
+ } catch (err) {
24
+ console.error('Error in jsonToCsv(): ', err)
25
+ }
26
+ }
27
+
28
+ jsonToCsv()
@@ -0,0 +1,3 @@
1
+ {
2
+ "memoryLogs": []
3
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "memoryLogs": []
3
+ }
@@ -0,0 +1,57 @@
1
+ /*
2
+ This is an example of how to start a Helia IPFS node with node.js and attach
3
+ the helia-coord library to it.
4
+ */
5
+
6
+ // Global npm libraries
7
+ import SlpWallet from 'minimal-slp-wallet'
8
+ import { memoryUsage } from 'node:process'
9
+ import fs from 'fs'
10
+
11
+ // Local libraries
12
+ import IpfsCoord from '../../index.js'
13
+ import CreateHeliaNode from './create-helia-node.js'
14
+
15
+ async function start () {
16
+ // Create an instance of bch-js and IPFS.
17
+ const wallet = new SlpWallet()
18
+ await wallet.walletInfoPromise
19
+
20
+ const createHeliaNode = new CreateHeliaNode()
21
+ const ipfs = await createHeliaNode.start()
22
+
23
+ // Pass bch-js and IPFS to ipfs-coord when instantiating it.
24
+ const ipfsCoord = new IpfsCoord({
25
+ ipfs,
26
+ wallet,
27
+ type: 'node.js',
28
+ // type: 'browser'
29
+ nodeType: 'external',
30
+ debugLevel: 2
31
+ })
32
+
33
+ await ipfsCoord.start()
34
+ console.log('IPFS and the coordination library is ready.')
35
+
36
+ setInterval(async function () {
37
+ try {
38
+ const memoryLog = JSON.parse(fs.readFileSync('./memory-log.json'))
39
+ // console.log('memoryLog: ', memoryLog)
40
+
41
+ const memory = memoryUsage()
42
+
43
+ const now = new Date()
44
+ memory.timestampIso = now.toISOString()
45
+ memory.timestampLocal = now.toLocaleString()
46
+ memory.timestampJs = now.getTime()
47
+
48
+ memoryLog.memoryLogs.push(memory)
49
+
50
+ await fs.writeFileSync('./memory-log.json', JSON.stringify(memoryLog, null, 2))
51
+ console.log(`Memory logged at ${now.toLocaleString()}`)
52
+ } catch (err) {
53
+ console.error('Error trying to measure memory: ', err)
54
+ }
55
+ }, 60000)
56
+ }
57
+ start()
package/index.js CHANGED
@@ -90,7 +90,7 @@ class IpfsCoord {
90
90
  this.useCases.pubsub.updateThisNode(this.thisNode)
91
91
 
92
92
  // Subscribe to Pubsub Channels
93
- // await this.useCases.pubsub.initializePubsub(this.thisNode)
93
+ // feature commented out
94
94
  await this.useCases.pubsub.initializePubsub({ controllers: this.controllers })
95
95
 
96
96
  // Start timer-based controllers.
@@ -76,14 +76,14 @@ class IpfsAdapter {
76
76
  // Attempts to connect to an IPFS peer, given its IPFS multiaddr.
77
77
  // Returns true if the connection succeeded. Otherwise returns false.
78
78
  async connectToPeer (inObj = {}) {
79
+ const { multiaddr } = inObj
80
+
79
81
  try {
80
82
  // console.log('connectToPeer() inObj: ', inObj)
81
83
 
82
84
  // TODO: Throw error if ipfs ID is passed, instead of a multiaddr.
83
85
  // console.log('ipfsAddr: ', ipfsAddr)
84
86
 
85
- const { multiaddr } = inObj
86
-
87
87
  // await this.ipfs.swarm.connect(ipfsAddr, { timeout: CONNECTION_TIMEOUT })
88
88
  await this.ipfs.libp2p.dial(this.multiaddr(multiaddr))
89
89
  // console.log('connectToPeer() result: ', result)
@@ -97,7 +97,7 @@ class IpfsAdapter {
97
97
  } catch (err) {
98
98
  /* exit quietly */
99
99
  // console.log('connectToPeer() Error connecting to peer: ', err)
100
- this.log.statusLog(2, 'Error trying to connect to peer node : ', err.message)
100
+ this.log.statusLog(2, `Error trying to connect to peer node ${multiaddr}: `, err.message)
101
101
 
102
102
  return {
103
103
  success: false,
@@ -81,9 +81,9 @@ class TimerControllers {
81
81
 
82
82
  // Periodically try to connect to problematic peers that advertise as
83
83
  // potential circuit relays.
84
- this.relaySearchHandle = setInterval(async function () {
85
- await _this.searchForRelays(thisNode, useCases)
86
- }, this.relaySearchInterval)
84
+ // this.relaySearchHandle = setInterval(async function () {
85
+ // await _this.searchForRelays(thisNode, useCases)
86
+ // }, this.relaySearchInterval)
87
87
 
88
88
  this.listPubsubChannelsHandle = setInterval(async function () {
89
89
  await _this.listPubsubChannels()
@@ -151,7 +151,7 @@ class PubsubUseCase {
151
151
  // Skip any repeated messages
152
152
  const shouldProcess = this.checkForDuplicateMsg(msg)
153
153
  if (!shouldProcess) {
154
- console.log('parseCoordPubsub() duplicate message.')
154
+ // console.log('parseCoordPubsub() duplicate message.')
155
155
  return false
156
156
  }
157
157
 
@@ -162,7 +162,7 @@ class PubsubUseCase {
162
162
  // Ignore this message if it originated from this IPFS node.
163
163
  const thisNodeId = this.adapters.ipfs.ipfsPeerId
164
164
  if (from === thisNodeId) {
165
- console.log('parseCoordPubsub() message came from this node.')
165
+ // console.log('parseCoordPubsub() message came from this node.')
166
166
  return false
167
167
  }
168
168
 
@@ -97,6 +97,7 @@ class ThisNodeUseCases {
97
97
 
98
98
  // Subscribe to my own pubsub channel, for receiving info from other peers.
99
99
  this.tempHandler = () => {} // This handler will be overwritten by handleNewMessage()
100
+
100
101
  selfData.pubsub = await this.adapters.pubsub.subscribeToPubsubChannel(
101
102
  selfData.ipfsId,
102
103
  this.tempHandler,
@@ -0,0 +1,12 @@
1
+ # Memory Usage
2
+
3
+ This is the same example app as the directory above, but it's been modified to take
4
+ periodic memory snapshots and write the memory usage to a JSON file. This is useful
5
+ for tracking potential memory leaks by monitoring memory usage over time.
6
+
7
+ ## Usage
8
+
9
+ Copy the `memory-log-example.json` to a new file called `memory-log.json`
10
+
11
+ Run this program with:
12
+ - `node start-node.js`
@@ -0,0 +1,154 @@
1
+ /*
2
+ This library creates a Helia IPFS node. This is done prior to attaching
3
+ helia-coord to the node.
4
+ This library is called by start-node.js.
5
+ */
6
+
7
+ // Global npm libraries
8
+ import { createHelia } from 'helia'
9
+ import fs from 'fs'
10
+ import { FsBlockstore } from 'blockstore-fs'
11
+ import { FsDatastore } from 'datastore-fs'
12
+ import { createLibp2p } from 'libp2p'
13
+ import { tcp } from '@libp2p/tcp'
14
+ import { noise } from '@chainsafe/libp2p-noise'
15
+ import { yamux } from '@chainsafe/libp2p-yamux'
16
+ // import { bootstrap } from '@libp2p/bootstrap'
17
+ // import { identifyService } from 'libp2p/identify'
18
+ import { identify } from '@libp2p/identify'
19
+ // import { circuitRelayTransport } from 'libp2p/circuit-relay'
20
+ import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'
21
+ import { gossipsub } from '@chainsafe/libp2p-gossipsub'
22
+ import { webSockets } from '@libp2p/websockets'
23
+ import { publicIpv4 } from 'public-ip'
24
+ import { multiaddr } from '@multiformats/multiaddr'
25
+ import { webRTC } from '@libp2p/webrtc'
26
+
27
+ const ROOT_DIR = './'
28
+ const IPFS_DIR = './.ipfsdata/ipfs'
29
+
30
+ class CreateHeliaNode {
31
+ constructor () {
32
+ this.publicIp = publicIpv4
33
+ }
34
+
35
+ // Start an IPFS node.
36
+ async start () {
37
+ try {
38
+ // Ensure the directory structure exists that is needed by the IPFS node to store data.
39
+ this.ensureBlocksDir()
40
+
41
+ // Create an IPFS node
42
+ const ipfs = await this.createNode()
43
+ // console.log('ipfs: ', ipfs)
44
+
45
+ this.id = ipfs.libp2p.peerId.toString()
46
+ console.log('IPFS ID: ', this.id)
47
+
48
+ // Attempt to guess our ip4 IP address.
49
+ const ip4 = await this.publicIp()
50
+ let detectedMultiaddr = `/ip4/${ip4}/tcp/4001/p2p/${this.id}`
51
+ detectedMultiaddr = multiaddr(detectedMultiaddr)
52
+
53
+ // Get the multiaddrs for the node.
54
+ const multiaddrs = ipfs.libp2p.getMultiaddrs()
55
+ multiaddrs.push(detectedMultiaddr)
56
+ console.log('Multiaddrs: ', multiaddrs)
57
+
58
+ this.multiaddrs = multiaddrs
59
+
60
+ // Signal that this adapter is ready.
61
+ this.isReady = true
62
+
63
+ this.ipfs = ipfs
64
+
65
+ return this.ipfs
66
+ } catch (err) {
67
+ console.error('Error in start()')
68
+
69
+ throw err
70
+ }
71
+ }
72
+
73
+ // This function creates an IPFS node using Helia.
74
+ // It returns the node as an object.
75
+ async createNode () {
76
+ try {
77
+ // Create block and data stores.
78
+ const blockstore = new FsBlockstore(`${IPFS_DIR}/blockstore`)
79
+ const datastore = new FsDatastore(`${IPFS_DIR}/datastore`)
80
+
81
+ // Configure services
82
+ const services = {
83
+ identify: identify(),
84
+ pubsub: gossipsub({ allowPublishToZeroPeers: true })
85
+ }
86
+
87
+ // libp2p is the networking layer that underpins Helia
88
+ const libp2p = await createLibp2p({
89
+ datastore,
90
+ addresses: {
91
+ listen: [
92
+ '/ip4/127.0.0.1/tcp/0',
93
+ '/ip4/0.0.0.0/tcp/4001',
94
+ '/ip4/0.0.0.0/tcp/4003/ws',
95
+ '/webrtc'
96
+ ]
97
+ },
98
+ transports: [
99
+ tcp(),
100
+ webSockets(),
101
+ circuitRelayTransport({ discoverRelays: 3 }),
102
+ webRTC()
103
+ ],
104
+ connectionEncryption: [
105
+ noise()
106
+ ],
107
+ streamMuxers: [
108
+ yamux()
109
+ ],
110
+ services
111
+ })
112
+
113
+ // create a Helia node
114
+ const helia = await createHelia({
115
+ blockstore,
116
+ datastore,
117
+ libp2p
118
+ })
119
+
120
+ return helia
121
+ } catch (err) {
122
+ console.error('Error creating Helia node: ', err)
123
+
124
+ throw err
125
+ }
126
+ }
127
+
128
+ async stop () {
129
+ await this.ipfs.stop()
130
+
131
+ return true
132
+ }
133
+
134
+ // Ensure that the directories exist to store blocks from the IPFS network.
135
+ // This function is called at startup, before the IPFS node is started.
136
+ ensureBlocksDir () {
137
+ try {
138
+ !fs.existsSync(`${ROOT_DIR}.ipfsdata`) && fs.mkdirSync(`${ROOT_DIR}.ipfsdata`)
139
+
140
+ !fs.existsSync(`${IPFS_DIR}`) && fs.mkdirSync(`${IPFS_DIR}`)
141
+
142
+ !fs.existsSync(`${IPFS_DIR}/blockstore`) && fs.mkdirSync(`${IPFS_DIR}/blockstore`)
143
+
144
+ !fs.existsSync(`${IPFS_DIR}/datastore`) && fs.mkdirSync(`${IPFS_DIR}/datastore`)
145
+
146
+ return true
147
+ } catch (err) {
148
+ console.error('Error in ensureBlocksDir(): ', err)
149
+ throw err
150
+ }
151
+ }
152
+ }
153
+
154
+ export default CreateHeliaNode
@@ -0,0 +1,28 @@
1
+ /*
2
+ This app converts the memory-log.json file to a CSV file that can be imported
3
+ into a spreadsheet for further analysis.
4
+ */
5
+
6
+ import fs from 'fs'
7
+
8
+ async function jsonToCsv () {
9
+ try {
10
+ const log = JSON.parse(fs.readFileSync('./memory-log.json'))
11
+ const memoryLogs = log.memoryLogs
12
+
13
+ let outStr = 'timestampIso,timestampJs,heapTotal (MB),heapUsed (MB),external (MB),arrayBuffers (MB),rss (MB)\n'
14
+
15
+ for (let i = 0; i < memoryLogs.length; i++) {
16
+ const thisLog = memoryLogs[i]
17
+
18
+ outStr += `${thisLog.timestampIso},${thisLog.timestampJs},${thisLog.heapTotal / 1000000},${thisLog.heapUsed / 1000000},${thisLog.external / 1000000},${thisLog.arrayBuffers / 1000000},${thisLog.rss / 1000000}\n`
19
+ }
20
+
21
+ await fs.writeFileSync('./memory-log.csv', outStr)
22
+ console.log('JSON memory log converted to CSV file.')
23
+ } catch (err) {
24
+ console.error('Error in jsonToCsv(): ', err)
25
+ }
26
+ }
27
+
28
+ jsonToCsv()
@@ -0,0 +1,3 @@
1
+ {
2
+ "memoryLogs": []
3
+ }