lian / bitcoin-ruby

bitcoin utils and protocol in ruby.
Other
922 stars 322 forks source link

Is this gem is threadsafe? #305

Open kot-begemot opened 4 years ago

kot-begemot commented 4 years ago

I was checking out the codebase and come to the conclusion that this gem might not work well with threaded applications. For example, performing parallel tasks in Unicorn or Sidekiq might cause a hard to debug issue.

I came to this conclusion after I discovered the way how the network is set up.

Bitcoin.network = :testnet3

So my question is, are there any plans to make this gem thread-safe? or perhaps would such changes be welcomed?

paradisaeidae commented 3 years ago

With Ruby-3 Ractors replace threads 'conceptually'. https://www.ruby-lang.org/en/news/2020/09/25/ruby-3-0-0-preview1-released/ "Ractor is an Actor-model like concurrent abstraction designed to provide a parallel execution feature without thread-safety concerns". "Additionally: Scheduler (Experimental) Thread#scheduler is introduced for intercepting blocking operations."

The latter requires gems such as Faraday to be Scheduler aware. This is being worked on at that layer by relevant gems. https://www.youtube.com/watch?v=OlmySf03GUo

krtschmr commented 3 years ago

Would you ever change the network in production during runtime across threads? It's the regular way of how to have configurations for a gem

kot-begemot commented 3 years ago

Yeap, I am. I am dealing with multiple networks though this gem

krtschmr commented 3 years ago

do you mind explaining why you need to switch networks in production? i would love to hear some experience and learn a usecase

kot-begemot commented 3 years ago

Sure. We provide swapping platform on the web and we are generating multisig addresses. Final multisig address is based on the network magic values. It all happens in the same app. We are using unicorn, which relays on threads. Some tasks are happening asyncronously, as they take time and we relay on this regards on Sidekiq. Currently we have to switch network for the whole app each time.

We can figure out some locking mechanism to ensure there won't be any interference from other threads or we can switch to other application server and to other job processors, but that all are workarounds.

IMHO network configurations should be defined per instance and not per class. That would solve an issue.