arj03 / ssb-browser-core

ssb-server in a browser
Other
50 stars 8 forks source link

Acquiring database lock - Only one instance of ssb-browser is allowed to run at a time. #40

Closed nichoth closed 3 years ago

nichoth commented 3 years ago

I get this error when starting this simple demo, not sure why -- https://github.com/nichoth/ssb-browser-demo

require('./ssb-singleton-setup')
const ssbSingleton = require('ssb-browser-core/ssb-singleton')

var [err, SSB] = ssbSingleton.getSSB()
console.log('in herererer', err, SSB)
arj03 commented 3 years ago

What do you mean by error? I should say so temporarily until it makes sure that it is the "leader" and can run. You can try and look in ssb-browser-demo to see how it is used.

nichoth commented 3 years ago

Thank you @arj03 . What i mean by error -- the err variable is set to "Acquiring database lock - Only one instance of ssb-browser is allowed to run at a time.", and the SSB variable is null. I don't know why as I only have the one process that is running ssb-browser.

I have been looking at ssb-browser-demo actually, the line with the error in my app is equivalent to https://github.com/arj03/ssb-browser-demo/blob/master/ui/browser.js#L219 in the browser-demo.

KyleMaas commented 3 years ago

Because of the way that the mutex stuff works, there is a short timeout when the singleton system first loads where it checks if any other windows are holding the lock. (Reason being that using localStorage for mutexes is about the only thread-safe way to do it across different windows/tabs in a widely-supported cross-platform manner, and we have a timeout system to watch for a dead controller and migrate to a different one, so there are hoops to jump through.) If you're calling getSSB() within that initial timeout, you'll get that error. As an alternative, you can use getSSBEventually() or getSimpleSSBEventually(), both of which call a callback function when a lock can be acquired. You can also register callbacks with onSuccess() which are called when a lock is acquired.

nichoth commented 3 years ago

Thanks @KyleMaas . I'm trying getSSBEventually, -- https://github.com/nichoth/ssb-browser-demo/blob/main/src/index.js#L4 -- however I'm uncertain of the signature of this function. It's returning another error:

Uncaught TypeError: ssbCheckCB is not a function

It looks like this is the place throwing the error -- https://github.com/arj03/ssb-browser-core/blob/master/ssb-singleton.js#L117 , but I'm not sure of what ssbCheckCB should be

KyleMaas commented 3 years ago

@nichoth I wrote up some docs for how SSB Singleton is supposed to work. See:

https://github.com/arj03/ssb-browser-core/tree/ssb-singleton-docs

You might want to get started with getSimpleSSBEventually(). It is a little simpler to use, covers most use cases, and only has two parameters:

KyleMaas commented 3 years ago

And in your defense, as much as we've tried to keep SSB Singleton easy to use where it requires minimal changes to code to port to a concurrency-safe version, it's still not exactly intuitive to use. Safe concurrency's hard. And for each bit of complexity in SSB Singleton, there's generally been some weird edge case that needed it. So if you have any other questions, feel free to ask.

Also, there were two main use cases we needed to cover:

nichoth commented 3 years ago

thanks @KyleMaas it works now

require('./ssb-singleton-setup')
const ssbSingleton = require('ssb-browser-core/ssb-singleton')

// (isRelevantCB, resultCB)
ssbSingleton.getSimpleSSBEventually(() => true, function (err, SSB) {
    console.log('aaaaaa', err, SSB)
})

ssbSingleton.onError(function (err) {
    console.log('errrrr', err)
})
ssbSingleton.onSuccess(function () {
    console.log('success', arguments)
})