amark / gun

An open source cybersecurity protocol for syncing decentralized graph data.
https://gun.eco/docs
Other
17.96k stars 1.16k forks source link

Unable to save Brain.js state file in GUN #1312

Closed Vectorrent closed 1 year ago

Vectorrent commented 1 year ago

I am having trouble saving a large object in GUN and Node.js. Every time I try, it fails silently, with no error messages.

I posted about this in the Matrix server, and Mark asked me to open an issue here.

GUN version: 0.2020.1239 Node.js version: v12.22.9 (also tested on v19.6.1)

This is the object in question: https://pastebin.com/v4rqWN4d

And here is the basic code:

const gun = Gun({
  peers: ['http://ctx:9666/gun', 'https://59.thesource.fm/gun'],
  file: './hive',
  localStorage: false,
  radisk: true,
  axe: true
})

const state = gun
  .get('brain')
  .get('state')
  .get('payload')
  .on(async (node) => {
      console.log(node)
  })

const myObject = "" // [See this link](https://pastebin.com/v4rqWN4d)

const object = JSON.parse(JSON.stringify(myObject))

gun.get('payload').put(object)

Like I said, there are no error messages, but the listener does not fire. It was suggested to convert the 1e-8 scientific notation in the JSON file to a string, which I've also tried - but it doesn't fix the problem.

Any ideas? I can just stringify the object for now, but that's obviously a bad solution, in the long-term.

Thanks in advance for any help you can offer.

draeder commented 1 year ago

The issue is that you aren't putting the object to the correct graph. The graph you are listening on is:

const state = gun
  .get('brain')
  .get('state')
  .get('payload')
  .on(async (node) => {
      console.log(node)
  })

But you are putting on:

gun.get('payload').put(object)

You should be putting on the graph you are listening on:

 gun
  .get('brain')
  .get('state')
  .get('payload')
  .put(object)
Vectorrent commented 1 year ago

Yikes, that was quite the oversight on my part. At one point, this was correct, but during the course of troubleshooting - I screwed up.

I just fixed the mistake, and now - the listener fires properly. Unfortunately, all I'm seeing is an old, stale version of the object returned. I've seen this problem before, and my solution was to use a different key.

So for now, I've moved to .get('brain3') and the listener is working okay. I'm not sure why keys can break like this, but I'm tentatively making progress, for now.

Thanks for the push in the right direction. I'll close this issue shortly, assuming I don't run into more trouble.

draeder commented 1 year ago

@LuciferianInk happens to the best of us. 🔢

If you aren't using a relay peer, you can clear the old data by clearing local storage in the browser, or by deleting the radata folder from your project in node.js. If you are using a relay peer, you can set object = null on a run, then try again with the regular code.

To only get the latest state:

let was
const state = gun
  .get('brain')
  .get('state')
  .get('payload')
  .on(async (node) => {
      if(was == node) return
      console.log(node)
      was = node
  })
Vectorrent commented 1 year ago

@draeder Thanks for the info. I was familiar with those tricks, but the code snippet is nice. That's a bit cleaner than what I'm doing in a few different places. I'll definitely be adopting that strategy!

So far, so good with my previous issue. Thanks a bunch for the help! I'll close this issue for now.