1
+ using System ;
2
+ using System . IO ;
3
+ using NewLife . Collections ;
4
+ using NewLife . Log ;
5
+ using NewLife . Net ;
6
+
7
+ namespace NewLife . Caching
8
+ {
9
+ /// <summary>服务器节点。内部连接池</summary>
10
+ class Node
11
+ {
12
+ #region 属性
13
+ /// <summary>拥有者</summary>
14
+ public Redis Owner { get ; set ; }
15
+
16
+ /// <summary>当前节点地址</summary>
17
+ public NetUri Uri { get ; set ; }
18
+ #endregion
19
+
20
+ #region 客户端池
21
+ class MyPool : ObjectPool < RedisClient >
22
+ {
23
+ public Node Node { get ; set ; }
24
+
25
+ protected override RedisClient OnCreate ( )
26
+ {
27
+ var node = Node ;
28
+ var rds = node . Owner ;
29
+ var uri = node . Uri ;
30
+ if ( uri == null ) throw new ArgumentNullException ( nameof ( node . Uri ) ) ;
31
+
32
+ if ( uri . Port == 0 ) uri . Port = 6379 ;
33
+
34
+ var rc = new RedisClient
35
+ {
36
+ Server = uri ,
37
+ Password = rds . Password ,
38
+ } ;
39
+
40
+ rc . Log = rds . Log ;
41
+ if ( rds . Db > 0 ) rc . Select ( rds . Db ) ;
42
+
43
+ return rc ;
44
+ }
45
+
46
+ protected override Boolean OnGet ( RedisClient value )
47
+ {
48
+ // 借出时清空残留
49
+ value ? . Reset ( ) ;
50
+
51
+ return base . OnGet ( value ) ;
52
+ }
53
+ }
54
+
55
+ private MyPool _Pool ;
56
+ /// <summary>连接池</summary>
57
+ public IPool < RedisClient > Pool
58
+ {
59
+ get
60
+ {
61
+ if ( _Pool != null ) return _Pool ;
62
+ lock ( this )
63
+ {
64
+ if ( _Pool != null ) return _Pool ;
65
+
66
+ var pool = new MyPool
67
+ {
68
+ Name = Owner . Name + "Pool" ,
69
+ Node = this ,
70
+ Min = 2 ,
71
+ Max = 1000 ,
72
+ IdleTime = 20 ,
73
+ AllIdleTime = 120 ,
74
+ Log = Owner . Log ,
75
+ } ;
76
+
77
+ return _Pool = pool ;
78
+ }
79
+ }
80
+ }
81
+
82
+ /// <summary>执行命令</summary>
83
+ /// <typeparam name="TResult">返回类型</typeparam>
84
+ /// <param name="func">回调函数</param>
85
+ /// <param name="write">是否写入操作</param>
86
+ /// <returns></returns>
87
+ public virtual TResult Execute < TResult > ( Func < RedisClient , TResult > func , Boolean write = false )
88
+ {
89
+ // 统计性能
90
+ var sw = Owner . Counter ? . StartCount ( ) ;
91
+
92
+ var i = 0 ;
93
+ do
94
+ {
95
+ // 每次重试都需要重新从池里借出连接
96
+ var client = Pool . Get ( ) ;
97
+ try
98
+ {
99
+ client . Reset ( ) ;
100
+ var rs = func ( client ) ;
101
+
102
+ Owner . Counter ? . StopCount ( sw ) ;
103
+
104
+ return rs ;
105
+ }
106
+ catch ( InvalidDataException )
107
+ {
108
+ if ( i ++ >= Owner . Retry ) throw ;
109
+ }
110
+ finally
111
+ {
112
+ Pool . Put ( client ) ;
113
+ }
114
+ } while ( true ) ;
115
+ }
116
+ #endregion
117
+ }
118
+ }
0 commit comments