@@ -23,6 +23,11 @@ internal class NodeEntry
23
23
/// </summary>
24
24
private NodeChildrenChangeHandler _childrenChangeHandler ;
25
25
26
+ /// <summary>
27
+ /// 节点的快照。
28
+ /// </summary>
29
+ private NodeSnapshot _localSnapshot = default ( NodeSnapshot ) ;
30
+
26
31
#endregion Field
27
32
28
33
#region Property
@@ -48,6 +53,8 @@ public async Task<IEnumerable<byte>> GetDataAsync(bool watch = false)
48
53
var zookeeper = _client . ZooKeeper ;
49
54
var data = await zookeeper . getDataAsync ( Path , watch ) ;
50
55
56
+ _localSnapshot . SetData ( data ? . Data ) ;
57
+
51
58
return data ? . Data ;
52
59
}
53
60
@@ -56,6 +63,8 @@ public async Task<IEnumerable<string>> GetChildrenAsync(bool watch = false)
56
63
var zookeeper = _client . ZooKeeper ;
57
64
var data = await zookeeper . getChildrenAsync ( Path , watch ) ;
58
65
66
+ _localSnapshot . SetChildrens ( data ? . Children ) ;
67
+
59
68
return data ? . Children ;
60
69
}
61
70
@@ -64,25 +73,39 @@ public async Task<bool> ExistsAsync(bool watch = false)
64
73
var zookeeper = _client . ZooKeeper ;
65
74
var data = await zookeeper . existsAsync ( Path , watch ) ;
66
75
67
- return data != null ;
76
+ var exists = data != null ;
77
+
78
+ _localSnapshot . SetExists ( exists ) ;
79
+
80
+ return exists ;
68
81
}
69
82
70
83
public async Task < string > CreateAsync ( byte [ ] data , List < ACL > acls , CreateMode createMode )
71
84
{
72
85
var zooKeeper = _client . ZooKeeper ;
73
- return await zooKeeper . createAsync ( Path , data , acls , createMode ) ;
86
+ var path = await zooKeeper . createAsync ( Path , data , acls , createMode ) ;
87
+
88
+ _localSnapshot . Create ( createMode , data , acls ) ;
89
+
90
+ return path ;
74
91
}
75
92
76
93
public Task < Stat > SetDataAsync ( byte [ ] data , int version = - 1 )
77
94
{
78
95
var zooKeeper = _client . ZooKeeper ;
79
- return zooKeeper . setDataAsync ( Path , data , version ) ;
96
+ var stat = zooKeeper . setDataAsync ( Path , data , version ) ;
97
+
98
+ _localSnapshot . Update ( data , version ) ;
99
+
100
+ return stat ;
80
101
}
81
102
82
- public Task DeleteAsync ( int version = - 1 )
103
+ public async Task DeleteAsync ( int version = - 1 )
83
104
{
84
105
var zookeeper = _client . ZooKeeper ;
85
- return zookeeper . deleteAsync ( Path , version ) ;
106
+ await zookeeper . deleteAsync ( Path , version ) ;
107
+
108
+ _localSnapshot . Delete ( ) ;
86
109
}
87
110
88
111
#region Listener
@@ -175,6 +198,26 @@ internal async Task OnChange(WatchedEvent watchedEvent, bool isFirstConnection)
175
198
/// </summary>
176
199
private bool HasChildrenChangeHandler => HasHandler ( _childrenChangeHandler ) ;
177
200
201
+ /// <summary>
202
+ /// 状态变更处理。
203
+ /// </summary>
204
+ /// <param name="watchedEvent"></param>
205
+ /// <param name="isFirstConnection">是否是zk第一次连接上服务器。</param>
206
+ private async Task OnStatusChangeHandle ( WatchedEvent watchedEvent , bool isFirstConnection )
207
+ {
208
+ //第一次连接zk不进行通知
209
+ if ( isFirstConnection )
210
+ return ;
211
+
212
+ //尝试恢复节点
213
+ await RestoreEphemeral ( ) ;
214
+
215
+ if ( HasDataChangeHandler )
216
+ await OnDataChangeHandle ( watchedEvent ) ;
217
+ if ( HasChildrenChangeHandler )
218
+ await OnChildrenChangeHandle ( watchedEvent ) ;
219
+ }
220
+
178
221
private async Task OnDataChangeHandle ( WatchedEvent watchedEvent )
179
222
{
180
223
if ( ! HasDataChangeHandler )
@@ -220,23 +263,6 @@ private async Task OnDataChangeHandle(WatchedEvent watchedEvent)
220
263
await WatchDataChange ( ) ;
221
264
}
222
265
223
- /// <summary>
224
- /// 状态变更处理。
225
- /// </summary>
226
- /// <param name="watchedEvent"></param>
227
- /// <param name="isFirstConnection">是否是zk第一次连接上服务器。</param>
228
- private async Task OnStatusChangeHandle ( WatchedEvent watchedEvent , bool isFirstConnection )
229
- {
230
- //第一次连接zk不进行通知
231
- if ( isFirstConnection )
232
- return ;
233
-
234
- if ( HasDataChangeHandler )
235
- await OnDataChangeHandle ( watchedEvent ) ;
236
- if ( HasChildrenChangeHandler )
237
- await OnChildrenChangeHandle ( watchedEvent ) ;
238
- }
239
-
240
266
private async Task OnChildrenChangeHandle ( WatchedEvent watchedEvent )
241
267
{
242
268
if ( ! HasChildrenChangeHandler )
@@ -261,16 +287,18 @@ private async Task OnChildrenChangeHandle(WatchedEvent watchedEvent)
261
287
switch ( watchedEvent . get_Type ( ) )
262
288
{
263
289
case Watcher . Event . EventType . NodeCreated :
264
- args = new NodeChildrenChangeArgs ( Path , Watcher . Event . EventType . NodeCreated , await getCurrentChildrens ( ) ) ;
290
+ args = new NodeChildrenChangeArgs ( Path , Watcher . Event . EventType . NodeCreated ,
291
+ await getCurrentChildrens ( ) ) ;
265
292
break ;
266
293
267
294
case Watcher . Event . EventType . NodeDeleted :
268
295
args = new NodeChildrenChangeArgs ( Path , Watcher . Event . EventType . NodeDeleted , null ) ;
269
296
break ;
270
297
271
298
case Watcher . Event . EventType . NodeChildrenChanged :
272
- case Watcher . Event . EventType . None : //重连时触发
273
- args = new NodeChildrenChangeArgs ( Path , Watcher . Event . EventType . NodeChildrenChanged , await getCurrentChildrens ( ) ) ;
299
+ case Watcher . Event . EventType . None : //重连时触发
300
+ args = new NodeChildrenChangeArgs ( Path , Watcher . Event . EventType . NodeChildrenChanged ,
301
+ await getCurrentChildrens ( ) ) ;
274
302
break ;
275
303
276
304
default :
@@ -309,6 +337,103 @@ private static bool HasHandler(MulticastDelegate multicast)
309
337
return multicast != null && multicast . GetInvocationList ( ) . Any ( ) ;
310
338
}
311
339
340
+ private async Task RestoreEphemeral ( )
341
+ {
342
+ //没有开启恢复
343
+ if ( ! _client . Options . EnableEphemeralNodeRestore )
344
+ return ;
345
+
346
+ //节点不存在
347
+ if ( ! _localSnapshot . IsExist )
348
+ return ;
349
+
350
+ //不是短暂的节点
351
+ if ( _localSnapshot . Mode != CreateMode . EPHEMERAL && _localSnapshot . Mode != CreateMode . EPHEMERAL_SEQUENTIAL )
352
+ return ;
353
+
354
+ try
355
+ {
356
+ await _client . RetryUntilConnected ( async ( ) =>
357
+ {
358
+ try
359
+ {
360
+ return await CreateAsync ( _localSnapshot . Data ? . ToArray ( ) , _localSnapshot . Acls , _localSnapshot . Mode ) ;
361
+ }
362
+ catch ( KeeperException . NodeExistsException ) //节点已经存在则忽略
363
+ {
364
+ return Path ;
365
+ }
366
+ } ) ;
367
+ }
368
+ catch ( Exception exception )
369
+ {
370
+ Console . WriteLine ( $ "恢复节点失败,异常:{ exception . Message } ") ;
371
+ }
372
+ }
373
+
312
374
#endregion Private Method
375
+
376
+ #region Help Type
377
+
378
+ public struct NodeSnapshot
379
+ {
380
+ public bool IsExist { get ; set ; }
381
+ public CreateMode Mode { get ; set ; }
382
+ public IEnumerable < byte > Data { get ; set ; }
383
+ public int ? Version { get ; set ; }
384
+ public List < ACL > Acls { get ; set ; }
385
+ public IEnumerable < string > Childrens { get ; set ; }
386
+
387
+ public void Create ( CreateMode mode , byte [ ] data , List < ACL > acls )
388
+ {
389
+ IsExist = true ;
390
+ Mode = mode ;
391
+ Data = data ;
392
+ Version = - 1 ;
393
+ Acls = acls ;
394
+ Childrens = null ;
395
+ }
396
+
397
+ public void Update ( IEnumerable < byte > data , int version )
398
+ {
399
+ IsExist = true ;
400
+ Data = data ;
401
+ Version = version ;
402
+ }
403
+
404
+ public void Delete ( )
405
+ {
406
+ IsExist = false ;
407
+ Mode = null ;
408
+ Data = null ;
409
+ Version = null ;
410
+ Acls = null ;
411
+ Childrens = null ;
412
+ }
413
+
414
+ public void SetData ( IEnumerable < byte > data )
415
+ {
416
+ IsExist = true ;
417
+ Data = data ;
418
+ }
419
+
420
+ public void SetChildrens ( IEnumerable < string > childrens )
421
+ {
422
+ IsExist = true ;
423
+ Childrens = childrens ;
424
+ }
425
+
426
+ public void SetExists ( bool exists )
427
+ {
428
+ if ( ! exists )
429
+ {
430
+ Delete ( ) ;
431
+ return ;
432
+ }
433
+ IsExist = true ;
434
+ }
435
+ }
436
+
437
+ #endregion Help Type
313
438
}
314
439
}
0 commit comments