├── .gitignore
├── .nuget
├── NuGet.Config
├── NuGet.exe
└── NuGet.targets
├── README.md
├── Rachis.Tests
├── BasicTests.cs
├── CommandsTests.cs
├── DictionaryCommand.cs
├── DictionaryStateMachine.cs
├── ElectionRelatedTests.cs
├── Http
│ ├── ElectionRelatedTests.cs
│ ├── HttpRaftTestsBase.cs
│ └── HttpTransportPingTest.cs
├── NLog.config
├── Properties
│ └── AssemblyInfo.cs
├── Rachis.Tests.csproj
├── RaftTestBaseWithHttp.cs
├── RaftTestsBase.cs
├── SnapshotTests.cs
├── TopologyChangesTests.cs
└── packages.config
├── Rachis.sln
├── Rachis.userprefs
├── Rachis
├── Behaviors
│ ├── AbstractRaftStateBehavior.cs
│ ├── CandidateStateBehavior.cs
│ ├── FollowerStateBehavior.cs
│ ├── LeaderStateBehavior.cs
│ ├── SnapshotInstallationStateBehavior.cs
│ └── SteppingDownStateBehavior.cs
├── Commands
│ ├── Command.cs
│ ├── NopCommand.cs
│ └── TopologyChangeCommand.cs
├── Interfaces
│ ├── ICommandSerializer.cs
│ ├── IRaftStateMachine.cs
│ ├── ISnapshotWriter.cs
│ └── ITransport.cs
├── JsonCommandSerializer.cs
├── MessageAbsolutePath.cs
├── Messages
│ ├── AppendEntriesRequest.cs
│ ├── AppendEntriesResponse.cs
│ ├── BaseMessage.cs
│ ├── CanInstallSnapshotRequest.cs
│ ├── CanInstallSnapshotResponse.cs
│ ├── InstallSnapshotRequest.cs
│ ├── InstallSnapshotResponse.cs
│ ├── LogEntry.cs
│ ├── MessageContext.cs
│ ├── RequestVoteRequest.cs
│ ├── RequestVoteResponse.cs
│ └── TimeoutNowRequest.cs
├── Properties
│ └── AssemblyInfo.cs
├── Rachis.csproj
├── RaftEngine.cs
├── RaftEngineOptions.cs
├── RaftEngineState.cs
├── Storage
│ ├── PersistentState.cs
│ └── Topology.cs
├── Transport
│ ├── HttpTransport.cs
│ ├── HttpTransportBus.cs
│ ├── HttpTransportSender.cs
│ ├── InMemoryTransportHub.cs
│ ├── NodeConnectionInfo.cs
│ ├── RaftController.cs
│ └── RaftWebApiConfig.cs
├── Utils
│ └── NotLeadingException.cs
└── packages.config
├── TailFeather.Client
├── Properties
│ └── AssemblyInfo.cs
├── TailFeather.Client.csproj
├── TailFeatherClient.cs
├── TailFeatherTopology.cs
└── packages.config
├── TailFeather
├── Controllers
│ ├── AdminController.cs
│ ├── KeyValueController.cs
│ └── TailFeatherController.cs
├── NLog.config
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── Storage
│ ├── KeyValueOperation.cs
│ ├── KeyValueOperationTypes.cs
│ ├── KeyValueStateMachine.cs
│ └── OperationBatchCommand.cs
├── TailFeather.csproj
├── TailFeatherCommandLineOptions.cs
├── app.config
└── packages.config
├── Tryouts
├── App.config
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── Tryouts.csproj
└── packages.config
└── license.txt
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.sln.docstates
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Dd]ebugPublic/
12 | [Rr]elease/
13 | x64/
14 | build/
15 | bld/
16 | [Bb]in/
17 | [Oo]bj/
18 |
19 | # MSTest test Results
20 | [Tt]est[Rr]esult*/
21 | [Bb]uild[Ll]og.*
22 |
23 | #NUNIT
24 | *.VisualState.xml
25 | TestResult.xml
26 |
27 | # Build Results of an ATL Project
28 | [Dd]ebugPS/
29 | [Rr]eleasePS/
30 | dlldata.c
31 |
32 | *_i.c
33 | *_p.c
34 | *_i.h
35 | *.ilk
36 | *.meta
37 | *.obj
38 | *.pch
39 | *.pdb
40 | *.pgc
41 | *.pgd
42 | *.rsp
43 | *.sbr
44 | *.tlb
45 | *.tli
46 | *.tlh
47 | *.tmp
48 | *.tmp_proj
49 | *.log
50 | *.vspscc
51 | *.vssscc
52 | .builds
53 | *.pidb
54 | *.svclog
55 | *.scc
56 |
57 | # Chutzpah Test files
58 | _Chutzpah*
59 |
60 | # Visual C++ cache files
61 | ipch/
62 | *.aps
63 | *.ncb
64 | *.opensdf
65 | *.sdf
66 | *.cachefile
67 |
68 | # Visual Studio profiler
69 | *.psess
70 | *.vsp
71 | *.vspx
72 |
73 | # TFS 2012 Local Workspace
74 | $tf/
75 |
76 | # Guidance Automation Toolkit
77 | *.gpState
78 |
79 | # ReSharper is a .NET coding add-in
80 | _ReSharper*/
81 | *.[Rr]e[Ss]harper
82 | *.DotSettings.user
83 |
84 | # JustCode is a .NET coding addin-in
85 | .JustCode
86 |
87 | # TeamCity is a build add-in
88 | _TeamCity*
89 |
90 | # DotCover is a Code Coverage Tool
91 | *.dotCover
92 |
93 | # NCrunch
94 | *.ncrunch*
95 | _NCrunch_*
96 | .*crunch*.local.xml
97 |
98 | # MightyMoose
99 | *.mm.*
100 | AutoTest.Net/
101 |
102 | # Web workbench (sass)
103 | .sass-cache/
104 |
105 | # Installshield output folder
106 | [Ee]xpress/
107 |
108 | # DocProject is a documentation generator add-in
109 | DocProject/buildhelp/
110 | DocProject/Help/*.HxT
111 | DocProject/Help/*.HxC
112 | DocProject/Help/*.hhc
113 | DocProject/Help/*.hhk
114 | DocProject/Help/*.hhp
115 | DocProject/Help/Html2
116 | DocProject/Help/html
117 |
118 | # Click-Once directory
119 | publish/
120 |
121 | # Publish Web Output
122 | *.[Pp]ublish.xml
123 | *.azurePubxml
124 |
125 | # NuGet Packages Directory
126 | packages/
127 | ## TODO: If the tool you use requires repositories.config uncomment the next line
128 | #!packages/repositories.config
129 |
130 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
131 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
132 | !packages/build/
133 |
134 | # Windows Azure Build Output
135 | csx/
136 | *.build.csdef
137 |
138 | # Windows Store app package directory
139 | AppPackages/
140 |
141 | # Others
142 | sql/
143 | *.Cache
144 | ClientBin/
145 | [Ss]tyle[Cc]op.*
146 | ~$*
147 | *~
148 | *.dbmdl
149 | *.dbproj.schemaview
150 | *.pfx
151 | *.publishsettings
152 | node_modules/
153 |
154 | # RIA/Silverlight projects
155 | Generated_Code/
156 |
157 | # Backup & report files from converting an old project file to a newer
158 | # Visual Studio version. Backup files are not needed, because we have git ;-)
159 | _UpgradeReport_Files/
160 | Backup*/
161 | UpgradeLog*.XML
162 | UpgradeLog*.htm
163 |
164 | # SQL Server files
165 | *.mdf
166 | *.ldf
167 |
168 | # Business Intelligence projects
169 | *.rdl.data
170 | *.bim.layout
171 | *.bim_*.settings
172 |
173 | # Microsoft Fakes
174 | FakesAssemblies/
175 |
--------------------------------------------------------------------------------
/.nuget/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.nuget/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ayende/Rachis/fc623a48f3ee2f170f2f178d0ff04fe085c84a96/.nuget/NuGet.exe
--------------------------------------------------------------------------------
/.nuget/NuGet.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildProjectDirectory)\..\
5 |
6 |
7 | false
8 |
9 |
10 | false
11 |
12 |
13 | true
14 |
15 |
16 | false
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
31 |
32 |
33 |
34 |
35 | $(SolutionDir).nuget
36 |
37 |
38 |
39 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config
40 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config
41 |
42 |
43 |
44 | $(MSBuildProjectDirectory)\packages.config
45 | $(PackagesProjectConfig)
46 |
47 |
48 |
49 |
50 | $(NuGetToolsPath)\NuGet.exe
51 | @(PackageSource)
52 |
53 | "$(NuGetExePath)"
54 | mono --runtime=v4.0.30319 "$(NuGetExePath)"
55 |
56 | $(TargetDir.Trim('\\'))
57 |
58 | -RequireConsent
59 | -NonInteractive
60 |
61 | "$(SolutionDir) "
62 | "$(SolutionDir)"
63 |
64 |
65 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)
66 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
67 |
68 |
69 |
70 | RestorePackages;
71 | $(BuildDependsOn);
72 |
73 |
74 |
75 |
76 | $(BuildDependsOn);
77 | BuildPackage;
78 |
79 |
80 |
81 |
82 |
83 |
84 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
99 |
100 |
103 |
104 |
105 |
106 |
108 |
109 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Rhino.Raft
2 | ----------
3 | Implementation of Raft protocol for use with RavenDB
4 | Reference on the protocol can be found here https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf
5 |
--------------------------------------------------------------------------------
/Rachis.Tests/BasicTests.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 | using Xunit.Extensions;
3 |
4 | namespace Rachis.Tests
5 | {
6 | public class BasicTests : RaftTestsBase
7 | {
8 | [Theory]
9 | [InlineData(2)]
10 | [InlineData(3)]
11 | [InlineData(5)]
12 | [InlineData(7)]
13 | public void CanApplyCommitAcrossAllCluster(int amount)
14 | {
15 | var leader = CreateNetworkAndGetLeader(amount);
16 | var commits = WaitForCommitsOnCluster(machine =>
17 | machine.Data.ContainsKey("4"));
18 | for (int i = 0; i < 5; i++)
19 | {
20 | leader.AppendCommand(new DictionaryCommand.Set
21 | {
22 | Key = i.ToString(),
23 | Value = i
24 | });
25 | }
26 | commits.Wait();
27 |
28 | foreach (var node in Nodes)
29 | {
30 | for (int i = 0; i < 5; i++)
31 | {
32 | var dictionary = ((DictionaryStateMachine)node.StateMachine).Data;
33 | Assert.Equal(i, dictionary[i.ToString()]);
34 | }
35 | }
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/Rachis.Tests/CommandsTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using FizzWare.NBuilder;
7 | using FluentAssertions;
8 | using Rachis.Messages;
9 | using Xunit;
10 | using Xunit.Extensions;
11 |
12 | namespace Rachis.Tests
13 | {
14 | public class CommandsTests : RaftTestsBase
15 | {
16 | [Fact]
17 | public void When_command_committed_CompletionTaskSource_is_notified()
18 | {
19 | const int CommandCount = 5;
20 | var leader = CreateNetworkAndGetLeader(3);
21 | var commands = Builder.CreateListOfSize(CommandCount)
22 | .All()
23 | .With(x => x.Completion = new TaskCompletionSource