Neo: Problem accessing Blockchain object in Persist or Commit with Genesis Block

Created on 5 Apr 2019  Â·  11Comments  Â·  Source: neo-project/neo

I try to make a plugin with access to the mempool, something like this:

public class StatsPlugin : Plugin, IPersistencePlugin
    {
        public override string Name => "StatsPlugin";

        public override void Configure() { }

        public void OnCommit(Snapshot snapshot)
        {
            // Dead lock
            var c = Blockchain.Singleton.MemPool.Capacity;
        }

        public void OnPersist(Snapshot snapshot, IReadOnlyList<Blockchain.ApplicationExecuted> applicationExecutedList) { }

        public bool ShouldThrowExceptionFromCommit(Exception ex) => false;
    }

And you can see that you will get a deadlock, (just for genesis block i think)

discussion

Most helpful comment

I think it's time to adopt Dependency Injection to control project components dependencies automatically. We have an expert, @rodoufu can you start looking into it?

All 11 comments

Ok,

Is not a dead lock, is a problem of logic, because we can't use Blockchain with the GenesisBlock...

image

image

We should move singleton=this before this if?

Let me think a little bit about this, @shargon, but this part of the Genesis makes sense in a first view.

No. If you do so, other thread may access Blockchain without GenesisBlock.

@shargon, I took time to understand this flow you mentioned.
In this example you gave It will probably enter in a loop as you emphasized...aheuahuea

However, it is a specific situation.
Is there any interesting information to be obtained before Committing the GenesisBlock, @shargon?

I think it's time to adopt Dependency Injection to control project components dependencies automatically. We have an expert, @rodoufu can you start looking into it?

I agree with @igormcoelho that DI can help a lot in this kind of situation, most of the DI frameworks are ready to work with multiple threads, in a matter of fact, AutoFac is one of them that has been used with Akka, which I think can also be a good thing to the project.

Can you do a preview for us @rodoufu? Just a proof-of-concept on a fork, so we can evaluate and work upon it? I can help you understanding the basic structures and their connections.

Another great thing about using DI is that it will make a lot easier to write UT for the project.
What we can't inject we can mock.

Can you do a preview for us @rodoufu? Just a proof-of-concept on a fork, so we can evaluate and work upon it? I can help you understanding the basic structures and their connections.

Some time ago I have started a branch for this purpose, now I think it will need a merge but we can start over working on it.
https://github.com/rodoufu/neo/tree/IoC

@igormcoelho, your help with the basic structures and how they work with each other will be very much appreciated.

Providing some examples of how I think about doing this:
In the NeoContainer class, we can registrater all the dependencies and how to build then.
https://github.com/rodoufu/neo/blob/IoC/neo/NeoContainer.cs

When we initialize the Akka actor system we need to make it use the DI system by:
ActorSystem.UseAutofac(_neoContainer.Container);
As you can see in https://github.com/rodoufu/neo/blob/IoC/neo/NeoSystem.cs

After that, we need to change the Props creation to form the Create method to the DI method, something like:
return Akka.Actor.Props.Create(() => new Blockchain(system, store)).WithMailbox("blockchain-mailbox");
Replaced by:
return system.ActorSystem.DI().Props<Blockchain>().WithMailbox("blockchain-mailbox");

Then, every time we have a dependency to be satisfied we register it in the NeoContainer and just leave it as a dependency in the class we are creating and Autofac will inject it using constructor injection.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Tommo-L picture Tommo-L  Â·  66Comments

coranos picture coranos  Â·  85Comments

SueNEO picture SueNEO  Â·  30Comments

lock9 picture lock9  Â·  35Comments

erikzhang picture erikzhang  Â·  31Comments