Skip to content

Commit 94d2f31

Browse files
committed
初次提交。
1 parent 356bd58 commit 94d2f31

File tree

15 files changed

+1463
-0
lines changed

15 files changed

+1463
-0
lines changed

.gitattributes

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
###############################################################################
2+
# Set default behavior to automatically normalize line endings.
3+
###############################################################################
4+
* text=auto
5+
6+
###############################################################################
7+
# Set default behavior for command prompt diff.
8+
#
9+
# This is need for earlier builds of msysgit that does not have it on by
10+
# default for csharp files.
11+
# Note: This is only used by command line
12+
###############################################################################
13+
#*.cs diff=csharp
14+
15+
###############################################################################
16+
# Set the merge driver for project and solution files
17+
#
18+
# Merging from the command prompt will add diff markers to the files if there
19+
# are conflicts (Merging from VS is not affected by the settings below, in VS
20+
# the diff markers are never inserted). Diff markers may cause the following
21+
# file extensions to fail to load in VS. An alternative would be to treat
22+
# these files as binary and thus will always conflict and require user
23+
# intervention with every merge. To do so, just uncomment the entries below
24+
###############################################################################
25+
#*.sln merge=binary
26+
#*.csproj merge=binary
27+
#*.vbproj merge=binary
28+
#*.vcxproj merge=binary
29+
#*.vcproj merge=binary
30+
#*.dbproj merge=binary
31+
#*.fsproj merge=binary
32+
#*.lsproj merge=binary
33+
#*.wixproj merge=binary
34+
#*.modelproj merge=binary
35+
#*.sqlproj merge=binary
36+
#*.wwaproj merge=binary
37+
38+
###############################################################################
39+
# behavior for image files
40+
#
41+
# image files are treated as binary by default.
42+
###############################################################################
43+
#*.jpg binary
44+
#*.png binary
45+
#*.gif binary
46+
47+
###############################################################################
48+
# diff behavior for common document formats
49+
#
50+
# Convert binary document formats to text before diffing them. This feature
51+
# is only available from the command line. Turn it on by uncommenting the
52+
# entries below.
53+
###############################################################################
54+
#*.doc diff=astextplain
55+
#*.DOC diff=astextplain
56+
#*.docx diff=astextplain
57+
#*.DOCX diff=astextplain
58+
#*.dot diff=astextplain
59+
#*.DOT diff=astextplain
60+
#*.pdf diff=astextplain
61+
#*.PDF diff=astextplain
62+
#*.rtf diff=astextplain
63+
#*.RTF diff=astextplain
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.25420.1
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{382072F7-0554-45BA-91FC-274126A3BB65}"
7+
EndProject
8+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5280067A-3FB3-43E3-B4C9-67630A7AAD5F}"
9+
ProjectSection(SolutionItems) = preProject
10+
global.json = global.json
11+
EndProjectSection
12+
EndProject
13+
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Rabbit.Zookeeper", "src\Rabbit.Zookeeper\Rabbit.Zookeeper.xproj", "{48F4923D-B6A8-4C12-8A7B-706CCA73D465}"
14+
EndProject
15+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{31979019-CD33-49AE-8F1F-1F89021C78D7}"
16+
EndProject
17+
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Rabbit.Zookeeper.Tests", "tests\Rabbit.Zookeeper.Tests\Rabbit.Zookeeper.Tests.xproj", "{621F5DAC-2FAF-4D1F-AD7E-69585BB9E86E}"
18+
EndProject
19+
Global
20+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
21+
Debug|Any CPU = Debug|Any CPU
22+
Release|Any CPU = Release|Any CPU
23+
EndGlobalSection
24+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
25+
{48F4923D-B6A8-4C12-8A7B-706CCA73D465}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26+
{48F4923D-B6A8-4C12-8A7B-706CCA73D465}.Debug|Any CPU.Build.0 = Debug|Any CPU
27+
{48F4923D-B6A8-4C12-8A7B-706CCA73D465}.Release|Any CPU.ActiveCfg = Release|Any CPU
28+
{48F4923D-B6A8-4C12-8A7B-706CCA73D465}.Release|Any CPU.Build.0 = Release|Any CPU
29+
{621F5DAC-2FAF-4D1F-AD7E-69585BB9E86E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
30+
{621F5DAC-2FAF-4D1F-AD7E-69585BB9E86E}.Debug|Any CPU.Build.0 = Debug|Any CPU
31+
{621F5DAC-2FAF-4D1F-AD7E-69585BB9E86E}.Release|Any CPU.ActiveCfg = Release|Any CPU
32+
{621F5DAC-2FAF-4D1F-AD7E-69585BB9E86E}.Release|Any CPU.Build.0 = Release|Any CPU
33+
EndGlobalSection
34+
GlobalSection(SolutionProperties) = preSolution
35+
HideSolutionNode = FALSE
36+
EndGlobalSection
37+
GlobalSection(NestedProjects) = preSolution
38+
{48F4923D-B6A8-4C12-8A7B-706CCA73D465} = {382072F7-0554-45BA-91FC-274126A3BB65}
39+
{621F5DAC-2FAF-4D1F-AD7E-69585BB9E86E} = {31979019-CD33-49AE-8F1F-1F89021C78D7}
40+
EndGlobalSection
41+
EndGlobal

Rabbit.Zookeeper/global.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"projects": [ "src", "tests" ],
3+
"sdk": {
4+
"version": "1.0.0-preview2-003131"
5+
}
6+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using org.apache.zookeeper;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
5+
namespace Rabbit.Zookeeper
6+
{
7+
/// <summary>
8+
/// 连接状态变更事件参数。
9+
/// </summary>
10+
public class ConnectionStateChangeArgs
11+
{
12+
public Watcher.Event.KeeperState State { get; set; }
13+
}
14+
15+
/// <summary>
16+
/// 节点变更参数。
17+
/// </summary>
18+
public abstract class NodeChangeArgs
19+
{
20+
protected NodeChangeArgs(string path, Watcher.Event.EventType type)
21+
{
22+
Path = path;
23+
Type = type;
24+
}
25+
26+
/// <summary>
27+
/// 变更类型。
28+
/// </summary>
29+
public Watcher.Event.EventType Type { get; private set; }
30+
31+
/// <summary>
32+
/// 节点路径。
33+
/// </summary>
34+
public string Path { get; private set; }
35+
}
36+
37+
public sealed class NodeDataChangeArgs : NodeChangeArgs
38+
{
39+
public NodeDataChangeArgs(string path, Watcher.Event.EventType type, IEnumerable<byte> currentData) : base(path, type)
40+
{
41+
CurrentData = currentData;
42+
}
43+
44+
/// <summary>
45+
/// 当前节点数据(最新的)
46+
/// </summary>
47+
public IEnumerable<byte> CurrentData { get; private set; }
48+
}
49+
50+
public sealed class NodeChildrenChangeArgs : NodeChangeArgs
51+
{
52+
public NodeChildrenChangeArgs(string path, Watcher.Event.EventType type, IEnumerable<string> currentChildrens) : base(path, type)
53+
{
54+
CurrentChildrens = currentChildrens;
55+
}
56+
57+
/// <summary>
58+
/// 当前节点的子节点数据(最新的)
59+
/// </summary>
60+
public IEnumerable<string> CurrentChildrens { get; private set; }
61+
}
62+
63+
public delegate Task NodeDataChangeHandler(IZookeeperClient client, NodeDataChangeArgs args);
64+
65+
public delegate Task NodeChildrenChangeHandler(IZookeeperClient client, NodeChildrenChangeArgs args);
66+
67+
public delegate Task ConnectionStateChangeHandler(IZookeeperClient client, ConnectionStateChangeArgs args);
68+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
using org.apache.zookeeper;
2+
using org.apache.zookeeper.data;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Threading.Tasks;
6+
7+
namespace Rabbit.Zookeeper
8+
{
9+
public interface IZookeeperClient : IDisposable
10+
{
11+
/// <summary>
12+
/// 具体的zookeeper连接。
13+
/// </summary>
14+
ZooKeeper ZooKeeper { get; }
15+
16+
/// <summary>
17+
/// 客户端选项。
18+
/// </summary>
19+
ZookeeperClientOptions Options { get; }
20+
21+
/// <summary>
22+
/// 等待zk连接到具体的某一个状态。
23+
/// </summary>
24+
/// <param name="states">希望达到的状态。</param>
25+
/// <param name="timeout">最长等待时间。</param>
26+
/// <returns>如果成功则返回true,否则返回false。</returns>
27+
bool WaitForKeeperState(Watcher.Event.KeeperState states, TimeSpan timeout);
28+
29+
/// <summary>
30+
/// 重试直到zk连接上。
31+
/// </summary>
32+
/// <typeparam name="T">返回类型。</typeparam>
33+
/// <param name="callable">执行的zk操作。</param>
34+
/// <returns>执行结果。</returns>
35+
Task<T> RetryUntilConnected<T>(Func<Task<T>> callable);
36+
37+
Task<IEnumerable<byte>> GetDataAsync(string path);
38+
39+
Task<IEnumerable<string>> GetChildrenAsync(string path);
40+
41+
Task<bool> ExistsAsync(string path);
42+
43+
Task CreateAsync(string path, byte[] data, List<ACL> acls, CreateMode createMode);
44+
45+
Task<Stat> SetDataAsync(string path, byte[] data, int version = -1);
46+
47+
Task DeleteAsync(string path, int version = -1);
48+
49+
Task SubscribeDataChange(string path, NodeDataChangeHandler listener);
50+
51+
void UnSubscribeDataChange(string path, NodeDataChangeHandler listener);
52+
53+
void SubscribeStatusChange(ConnectionStateChangeHandler listener);
54+
55+
void UnSubscribeStatusChange(ConnectionStateChangeHandler listener);
56+
57+
Task<IEnumerable<string>> SubscribeChildrenChange(string path, NodeChildrenChangeHandler listener);
58+
59+
void UnSubscribeChildrenChange(string path, NodeChildrenChangeHandler listener);
60+
}
61+
62+
public static class ZookeeperClientExtensions
63+
{
64+
public static Task CreateEphemeralAsync(this IZookeeperClient client, string path, byte[] data)
65+
{
66+
return client.CreateEphemeralAsync(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE);
67+
}
68+
69+
public static Task CreateEphemeralAsync(this IZookeeperClient client, string path, byte[] data, List<ACL> acls)
70+
{
71+
return client.CreateAsync(path, data, acls, CreateMode.EPHEMERAL);
72+
}
73+
74+
public static Task CreatePersistentAsync(this IZookeeperClient client, string path, byte[] data)
75+
{
76+
return client.CreatePersistentAsync(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE);
77+
}
78+
79+
public static Task CreatePersistentAsync(this IZookeeperClient client, string path, byte[] data, List<ACL> acls)
80+
{
81+
return client.CreateAsync(path, data, acls, CreateMode.PERSISTENT);
82+
}
83+
84+
public static async Task<bool> DeleteRecursiveAsync(this IZookeeperClient client, string path)
85+
{
86+
IEnumerable<string> children;
87+
try
88+
{
89+
children = await client.GetChildrenAsync(path);
90+
}
91+
catch (KeeperException.NoNodeException)
92+
{
93+
return true;
94+
}
95+
96+
foreach (string subPath in children)
97+
{
98+
if (!await client.DeleteRecursiveAsync(path + "/" + subPath))
99+
{
100+
return false;
101+
}
102+
}
103+
await client.DeleteAsync(path);
104+
return true;
105+
}
106+
107+
public static Task CreateRecursiveAsync(this IZookeeperClient client, string path, byte[] data, CreateMode createMode)
108+
{
109+
return client.CreateRecursiveAsync(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, createMode);
110+
}
111+
112+
public static async Task CreateRecursiveAsync(this IZookeeperClient client, string path, byte[] data, List<ACL> acls, CreateMode createMode)
113+
{
114+
try
115+
{
116+
await client.CreateAsync(path, data, acls, createMode);
117+
}
118+
catch (KeeperException.NodeExistsException)
119+
{
120+
}
121+
catch (KeeperException.NoNodeException)
122+
{
123+
var parentDir = path.Substring(0, path.LastIndexOf('/'));
124+
await CreateRecursiveAsync(client, parentDir, null, acls, CreateMode.PERSISTENT);
125+
await client.CreateAsync(path, data, acls, createMode);
126+
}
127+
}
128+
129+
/// <summary>
130+
/// 等待直到zk连接成功,超时时间为zk选项中的操作超时时间配置值。
131+
/// </summary>
132+
/// <param name="client">zk客户端。</param>
133+
public static void WaitForRetry(this IZookeeperClient client)
134+
{
135+
client.WaitUntilConnected(client.Options.OperatingTimeout);
136+
}
137+
138+
/// <summary>
139+
/// 等待直到zk连接成功。
140+
/// </summary>
141+
/// <param name="client">zk客户端。</param>
142+
/// <param name="timeout">最长等待时间。</param>
143+
/// <returns>如果成功则返回true,否则返回false。</returns>
144+
public static bool WaitUntilConnected(this IZookeeperClient client, TimeSpan timeout)
145+
{
146+
return client.WaitForKeeperState(Watcher.Event.KeeperState.SyncConnected, timeout);
147+
}
148+
}
149+
}

0 commit comments

Comments
 (0)