Skip to content

Commit

Permalink
Merge pull request stratisproject#35 from quantumagi/kbdispose
Browse files Browse the repository at this point in the history
Refactor KeyValueStore disposal
  • Loading branch information
zeptin authored Dec 16, 2019
2 parents 052292d + 3030b66 commit 417e157
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 4 deletions.
29 changes: 29 additions & 0 deletions src/Stratis.Bitcoin/FullNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ public void Dispose()
this.logger.LogInformation("Disposing settings.");
this.Settings.Dispose();

// Dispose the node storage.
this.DisposeNodeStorage();

// Fire INodeLifetime.Stopped.
this.logger.LogInformation("Notify application has stopped.");
this.nodeLifetime.NotifyStopped();
Expand All @@ -305,5 +308,31 @@ public void Dispose()

this.State = FullNodeState.Disposed;
}

/// <summary>
/// Due to the potential shared nature of node storage it can't be up to any given
/// feature to deal with the disposal thereof. Instead we do it here for all
/// singleton storage objects during shutdown.
/// </summary>
private void DisposeNodeStorage()
{
// Identify classes that support the IKeyValueStore interface.
var storageClasses = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(x => x.GetTypes())
.Where(x => typeof(IKeyValueStore).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract);

// Find the class interfaces that are derived from IKeyValueStore...
foreach (Type type in storageClasses.SelectMany(x => x.GetInterfaces().Where(i => i.GetInterfaces().Any(i2 => i2.UnderlyingSystemType == typeof(IKeyValueStore)))))
{
// ...that are disposable...
var obj = this.Services.ServiceProvider.GetService(type) as IDisposable;
if (obj == null)
continue;

// ...and dispose them.
this.logger.LogInformation("Disposing node storage '{0}'.", obj.GetType().Name);
obj.Dispose();
}
}
}
}
5 changes: 3 additions & 2 deletions src/Stratis.Bitcoin/Interfaces/IKeyValueStoreRepository.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Stratis.Bitcoin.KeyValueStore;

namespace Stratis.Bitcoin.Interfaces
{
/// <summary>
/// Represents a glue-layer containing the basic methods that all key-value databases should support.
/// </summary>
public interface IKeyValueStoreRepository
public interface IKeyValueStoreRepository : IDisposable
{
/// <summary>
/// Initialize the underlying database / glue-layer.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ protected override void Dispose(bool disposing)

if (disposing)
{
this.Repository.Close();
this.Repository.Dispose();
}

this.disposed = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,20 @@ public virtual T Deserialize<T>(byte[] objBytes)

/// <inheritdoc />
public abstract void Close();

// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>Protected implementation of Dispose pattern.</summary>
/// <param name="disposing">Indicates whether disposing.</param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
this.Close();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public override byte[] Serialize<T>(T obj)

public override void Init(string rootPath)
{
this.Close();
this.storage = new DBreezeEngine(rootPath);
}

Expand Down Expand Up @@ -219,6 +220,8 @@ public override void OnRollback(KeyValueStoreTransaction keyValueStoreTransactio

public override void Close()
{
this.storage?.Dispose();
this.storage = null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ public override void Init(string rootPath)
CreateIfMissing = true,
};

this.Close();
this.Storage = new DB(options, rootPath);

Guard.NotNull(this.Storage, nameof(this.Storage));

for (this.nextTablePrefix = 1; ; this.nextTablePrefix++)
{
byte[] tableNameBytes = this.Storage.Get(new byte[] { 0, (byte)this.nextTablePrefix });
Expand Down Expand Up @@ -246,7 +249,8 @@ public override void OnRollback(KeyValueStoreTransaction keyValueStoreTransactio

public override void Close()
{
this.Storage.Close();
this.Storage?.Dispose();
this.Storage = null;
}
}
}

0 comments on commit 417e157

Please sign in to comment.