-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
README.txt
288 lines (244 loc) · 9.93 KB
/
README.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
========================================================================================
_____ _ ____ __ __ _____ _
| __ \ (_) | _ \ / _| / _| | __ \ | |
| |__) | _ _ __ __ _ | |_) | _ _ | |_ | |_ ___ _ __ | |__) || | _ _ ___
| _ / | || '_ \ / _` || _ < | | | || _|| _|/ _ \| '__|| ___/ | | | | | |/ __|
| | \ \ | || | | || (_| || |_) || |_| || | | | | __/| | | | | |____| |_| |\__ \
|_| \_\|_||_| |_| \__, ||____/ \__,_||_| |_| \___||_| |_| |______|\__,_||___/
__/ |
|___/
========================================================================================
Welcome to RingBufferPlus
=========================
RingBufferPlus a generic circular buffer (ring buffer) in C# with auto-scaler.
Key Features
============
- Conscious use of resources
- Designed to reduce buffer resources when unused
- **Under stressful conditions**, the RingBufferPlus tends to go to **maximum capacity** and stay until conditions return to normal.
- **Under low usage conditions**, The RingBufferPlus tends to go to **minimum capacity** and stay until conditions return to normal.
- Designed to work on **container (or not) mitigating cpu and memory usage** (Avoiding k8s upscale/downscale unnecessarily)
- Start/restart under **Fault conditions and/or Stress conditions**
- Set unique name for same buffer type
- Set the **default capacity** (Startup)
- Set the **minimum and maximum capacity** (optional)
- Set the conditions for scaling to maximum and minimum (optional)
- Automatic condition values based on capacity (value not required)
- Upscaling does **not need to remove** the buffer
- better performance and availability
- Downscaling does **not need to remove** the buffer when **no slave control**
- better performance and availability
- Downscaling **needs to remove all** buffering when **has slave control**
- Performance penalty
- Ensure consistency and relationship between Master and slave
- Set scale type **Automatic** , **Manual** or **Slave**
- Automatic: by free-resources on buffer
- Manual: User/Application defined using 'Switch To' command
- Slave : Indicates that the control is a slave scale type
- Set **buffer integrity** for each acquisition and **check all integrity when acquisition idle**. (optional)
- Set master-slave (optional) - **2 Ring Buffer with synchronization**
- Master controls slave scale
- Event with **scale change** information
- Executed in a separate thread asynchronously
- Associate the **logger** interface (optional)
- Define a user function for generated **errors** (optional)
- Executed in a separate thread asynchronously
- Command to **Invalidate and renew** the buffer when it is in an invalid state
- Warm up to full capacity **before starting application** (optional but **recommended**)
- Receive item from buffer with **success/failure** information and **elapsed time** for acquisition
- Sets a **time limit** for acquiring the item in the buffer
- Detailed information about operations when the minimum log is Debug/Trace (**not recommended**)
- Simple and clear **fluent syntax**
Visit the official page for more documentation :
https://fracerqueira.github.io/RingBufferPlus
PipeAndFilter was developed in C# with target frameworks:
- netstandard2.1
- .NET 6
- .NET 7
- .NET 8
*** What's new in V3.2.0 ***
============================
- Renamed command 'MasterScale' to 'ScaleUnit'
- Added parameter 'ScaleUnit' to set the scale type (automatic/manual)
- Now the user can manually set the scale change mode
- Removed command 'SlaveScale'
- Now use 'ScaleUnit' command with scale type Slave
- Removed command 'SampleUnit'
- Now time base unit and number of samples collected are parameters of the command 'ScaleUnit'
- Added new command 'SlaveControl' to set Slave Ringbuffer
- Better clarity of command intent
- Removed mandatory commands 'ScaleWhenFreeLessEq' , 'RollbackWhenFreeGreaterEq' for MaxCapacity commands
- Now it is automatically set when 'MaxCapacity' is set
- Removed mandatory commands 'ScaleWhenFreeGreaterEq' , 'RollbackWhenFreeLessEq' for MinCapacity commands
- Now it is automatically set when 'MinCapacity' is set
- Added new command 'SwithTo' for Ringbuffer service
- Now the user can manually set the scale change when scale type is manual
- Improvement: Downscaling does not need to remove all buffer when no slave control
- Better performance and availability
Examples
========
See folder:
https://github.com/FRACerqueira/RingBufferPlus/tree/main/samples
Generic Usage
=============
Sample-Console Usage (Minimal features with auto-scale)
-------------------------------------------------------
Random rnd = new();
var rb = RingBuffer<int>.New("MyBuffer", cts.Token)
.Capacity(8)
.Factory((cts) => { return rnd.Next(1, 10); })
.ScaleUnit(ScaleMode.Automatic)
.MinCapacity(4)
.MaxCapacity(20)
.BuildWarmup(out var completed);
...
using (var buffer = rb.Accquire(cts.Token))
{
if (bufferedItem.Successful)
{
try
{
//do something
}
catch
{
buffer.Invalidate();
}
}
}
Sample-api/web Usage (Minimal features without auto-scale)
----------------------------------------------------------
builder.Services.AddRingBuffer<int>("Mybuffer",(ringbuf, _) =>
{
return ringbuf
.Capacity(8)
.Factory((cts) => { return 10; })
.Build();
});
...
//If you do not use the 'Warmup Ring Buffer' command, the first access to acquire the buffer will be Warmup (not recommended)
app.WarmupRingBuffer<int>("Mybuffer");
...
[ApiController]
[Route("[controller]")]
public class MyController(IRingBufferService<int> ringBufferService) : ControllerBase
{
private readonly IRingBufferService<int> _ringBufferService = ringBufferService;
[HttpGet]
public ActionResult Get(CancellationToken token)
{
using (var buffer = _ringBufferService.Accquire(token))
{
if (bufferedItem.Successful)
{
try
{
//do something
}
catch
{
buffer.Invalidate();
}
}
}
}
}
Sample-api/web Usage (Minimal features with manual scale)
---------------------------------------------------------
builder.Services.AddRingBuffer<int>("Mybuffer",(ringbuf, _) =>
{
return ringbuf
.Capacity(8)
.Factory((cts) => { return 10; })
.ScaleUnit(ScaleMode.Manual)
.MinCapacity(2)
.MaxCapacity(12)
.Build();
});
...
//If you do not use the 'Warmup Ring Buffer' command, the first access to acquire the buffer will be Warmup (not recommended)
app.WarmupRingBuffer<int>("Mybuffer");
...
[ApiController]
[Route("[controller]")]
public class MyController(IRingBufferService<int> ringBufferService) : ControllerBase
{
private readonly IRingBufferService<int> _ringBufferService = ringBufferService;
[HttpGet]
public ActionResult Get(CancellationToken token)
{
using (var buffer = _ringBufferService.Accquire(token))
{
if (bufferedItem.Successful)
{
try
{
//do something
}
catch
{
buffer.Invalidate();
}
}
}
}
[HttpPatch]
[Route("/ChangeCapacity")]
public ActionResult ChangeCapacity(ScaleSwith scaleUnit)
{
_ringBufferService.SwithTo(scaleUnit);
return Ok();
}
}
RabbitMQ Usage
==============
RabbitMQ has **AutomaticRecovery** functionality. This feature must be **DISABLED** when RingbufferPlus uses AutoScale.
If the AutomaticRecovery functionality is activated, "ghost" buffers may occur (without RingbufferPlus control)
For more details see https://github.com/FRACerqueira/RingBufferPlus/tree/main/samples/RingBufferPlusBenchmarkSample
Sample-Console Master-Slave feature using RabbitMq (basic usage)
----------------------------------------------------------------
ConnectionFactory = new ConnectionFactory()
{
...
AutomaticRecoveryEnabled = false
};
...
connectionRingBuffer = RingBuffer<IConnection>.New("RabbitCnn")
.Capacity(2)
.Logger(applogger!)
.AccquireTimeout(TimeSpan.FromMilliseconds(500))
.OnError((log, error) =>
{
log?.LogError("{error}", error);
})
.Factory((cts) => ConnectionFactory.CreateConnection())
.ScaleUnit(ScaleMode.Slave)
.ReportScale((metric, log, cts) =>
{
log?.LogInformation($"RabbitCnn Report: [{metric.MetricDate}] Trigger {metric.Trigger} from {metric.FromCapacity} to {metric.ToCapacity}");
})
.MaxCapacity(10)
.MinCapacity(1)
.BuildWarmup(out completedCnn);
modelRingBuffer = RingBuffer<IModel>.New("RabbitChanels")
.Capacity(10)
.Logger(applogger!)
.OnError((log, error) =>
{
log?.LogError("{error}", error);
})
.Factory((cts) => ModelFactory(cts))
.BufferHealth((buffer) => buffer.IsOpen)
.ScaleUnit(ScaleMode.Automatic,10,TimeSpan.FromSeconds(10))
.ReportScale((metric, log, cts) =>
{
log?.LogInformation($"RabbitChanels Report: [{metric.MetricDate}] Trigger {metric.Trigger} from {metric.FromCapacity} to {metric.ToCapacity}");
})
.Slave(connectionRingBuffer)
.MaxCapacity(50)
.MinCapacity(2)
.BuildWarmup(out completedChanels);
License
=======
Copyright 2022 @ Fernando Cerqueira
RingBufferPlus project is licensed under the the MIT license.