Dreamine.Hybrid
1.0.3
Dreamine.Hybrid 프로젝트의 API와 구성 요소를 제공합니다.
Toggle main menu visibility
로딩중...
검색중...
일치하는것 없음
InMemoryHybridMessageBus.cs
이 파일의 문서화 페이지로 가기
1
using
Dreamine.Hybrid.Interfaces
;
2
using
System;
3
using
System.Collections.Concurrent;
4
using
System.Collections.Generic;
5
using
System.Linq;
6
using
System.Threading;
7
using
System.Threading.Tasks;
8
9
namespace
Dreamine.Hybrid.Messaging
10
{
19
public
sealed
class
InMemoryHybridMessageBus
:
IHybridMessageBus
20
{
29
private
readonly ConcurrentDictionary<Type, SubscriptionBucket>
_subscriptions
=
new
();
38
private
volatile
IHybridMessageBusExceptionHandler
_exceptionHandler
=
39
NullHybridMessageBusExceptionHandler
.
Instance
;
40
57
public
IHybridMessageBusExceptionHandler
ExceptionHandler
58
{
59
get
=>
_exceptionHandler
;
60
set
=>
_exceptionHandler
= value ??
throw
new
ArgumentNullException(nameof(value));
61
}
62
111
public
async Task
PublishAsync<TMessage>
(
112
TMessage message,
113
CancellationToken cancellationToken =
default
)
114
where TMessage :
IHybridMessage
115
{
116
if
(message is
null
)
117
{
118
throw
new
ArgumentNullException(nameof(message));
119
}
120
121
if
(!
_subscriptions
.TryGetValue(typeof(TMessage), out
SubscriptionBucket
? subscriptions))
122
{
123
return
;
124
}
125
126
Subscription
[] snapshot = subscriptions.CreateSnapshot();
127
128
foreach
(
Subscription
subscription
in
snapshot)
129
{
130
if
(cancellationToken.IsCancellationRequested)
131
{
132
return
;
133
}
134
135
if
(subscription.
IsDisposed
)
136
{
137
continue
;
138
}
139
140
if
(subscription.
Handler
is not Func<TMessage, CancellationToken, Task> handler)
141
{
142
continue
;
143
}
144
145
try
146
{
147
await handler(message, cancellationToken).ConfigureAwait(
false
);
148
}
149
catch
(OperationCanceledException) when (cancellationToken.IsCancellationRequested)
150
{
151
return
;
152
}
153
catch
(ObjectDisposedException)
154
{
155
subscription.
Dispose
();
156
}
157
catch
(InvalidOperationException)
158
{
159
subscription.
Dispose
();
160
}
161
catch
(NullReferenceException)
162
{
163
/*
164
* Blazor Server / SignalR circuit가 아직 준비되지 않았거나,
165
* 이미 해제된 컴포넌트가 메시지를 수신할 때 발생할 수 있다.
166
*
167
* 메시지 버스는 한 구독자 실패 때문에 전체 publish를 중단하면 안 된다.
168
* 해당 구독은 더 이상 안전하지 않다고 보고 제거한다.
169
*/
170
subscription.
Dispose
();
171
}
172
catch
(Exception ex)
173
{
174
// Individual subscriber failure must not stop delivery to remaining subscribers.
175
// Delegate to the configured handler so callers can observe the failure
176
// (e.g. by wiring a logging-backed handler) without coupling this assembly
177
// to a concrete logger. Default handler is a no-op.
178
_exceptionHandler
.Handle(ex, typeof(TMessage));
179
}
180
}
181
}
182
223
public
IDisposable
Subscribe<TMessage>
(
224
Func<TMessage, CancellationToken, Task> handler)
225
where TMessage :
IHybridMessage
226
{
227
if
(handler is
null
)
228
{
229
throw
new
ArgumentNullException(nameof(handler));
230
}
231
232
Type messageType = typeof(TMessage);
233
var subscription =
new
Subscription
(messageType, handler,
Unsubscribe
);
234
235
while
(
true
)
236
{
237
SubscriptionBucket
subscriptions =
_subscriptions
.GetOrAdd(
238
messageType,
239
_ =>
new
SubscriptionBucket
());
240
241
if
(subscriptions.
TryAdd
(subscription))
242
{
243
return
subscription;
244
}
245
246
_subscriptions
.TryRemove(
247
new
KeyValuePair<Type, SubscriptionBucket>(messageType, subscriptions));
248
}
249
}
250
267
private
void
Unsubscribe
(
Subscription
subscription)
268
{
269
if
(subscription is
null
)
270
{
271
return
;
272
}
273
274
if
(!
_subscriptions
.TryGetValue(subscription.
MessageType
, out
SubscriptionBucket
? subscriptions))
275
{
276
return
;
277
}
278
279
subscriptions.Remove(subscription);
280
281
if
(subscriptions.TryCloseIfEmpty())
282
{
283
_subscriptions
.TryRemove(
284
new
KeyValuePair<Type, SubscriptionBucket>(subscription.
MessageType
, subscriptions));
285
}
286
}
287
296
private
sealed
class
SubscriptionBucket
297
{
306
private
readonly List<Subscription>
_subscriptions
=
new
();
315
private
bool
_closed
;
316
341
public
bool
TryAdd
(
Subscription
subscription)
342
{
343
lock (
_subscriptions
)
344
{
345
if
(
_closed
)
346
{
347
return
false
;
348
}
349
350
_subscriptions
.Add(subscription);
351
return
true
;
352
}
353
}
354
371
public
Subscription
[]
CreateSnapshot
()
372
{
373
lock (
_subscriptions
)
374
{
375
return
_subscriptions
.ToArray();
376
}
377
}
378
395
public
void
Remove
(
Subscription
subscription)
396
{
397
lock (
_subscriptions
)
398
{
399
_subscriptions
.Remove(subscription);
400
}
401
}
402
419
public
bool
TryCloseIfEmpty
()
420
{
421
lock (
_subscriptions
)
422
{
423
if
(
_subscriptions
.Count != 0)
424
{
425
return
false
;
426
}
427
428
_closed
=
true
;
429
return
true
;
430
}
431
}
432
}
433
442
private
sealed
class
Subscription
: IDisposable
443
{
452
private
readonly Action<Subscription>
_unsubscribe
;
461
private
volatile
bool
_disposed
;
462
503
public
Subscription
(
504
Type messageType,
505
object
handler,
506
Action<Subscription> unsubscribe)
507
{
508
MessageType
= messageType ??
throw
new
ArgumentNullException(nameof(messageType));
509
Handler
= handler ??
throw
new
ArgumentNullException(nameof(handler));
510
_unsubscribe
= unsubscribe ??
throw
new
ArgumentNullException(nameof(unsubscribe));
511
}
512
521
public
Type
MessageType
{
get
; }
522
531
public
object
Handler
{
get
; }
532
541
public
bool
IsDisposed
=>
_disposed
;
542
551
public
void
Dispose
()
552
{
553
if
(
_disposed
)
554
{
555
return
;
556
}
557
558
_disposed
=
true
;
559
_unsubscribe
(
this
);
560
}
561
}
562
}
563
}
Dreamine.Hybrid.Interfaces
Definition
IHybridMessage.cs:4
Dreamine.Hybrid.Messaging
Definition
HybridMessageBase.cs:5
Dreamine.Hybrid.Interfaces.IHybridMessage
Definition
IHybridMessage.cs:14
Dreamine.Hybrid.Interfaces.IHybridMessageBus
Definition
IHybridMessageBus.cs:16
Dreamine.Hybrid.Interfaces.IHybridMessageBusExceptionHandler
Definition
IHybridMessageBusExceptionHandler.cs:22
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus
Definition
InMemoryHybridMessageBus.cs:20
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus._exceptionHandler
volatile IHybridMessageBusExceptionHandler _exceptionHandler
Definition
InMemoryHybridMessageBus.cs:38
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.Unsubscribe
void Unsubscribe(Subscription subscription)
Definition
InMemoryHybridMessageBus.cs:267
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.Subscribe< TMessage >
IDisposable Subscribe< TMessage >(Func< TMessage, CancellationToken, Task > handler)
Definition
InMemoryHybridMessageBus.cs:223
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.PublishAsync< TMessage >
async Task PublishAsync< TMessage >(TMessage message, CancellationToken cancellationToken=default)
Definition
InMemoryHybridMessageBus.cs:111
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.ExceptionHandler
IHybridMessageBusExceptionHandler ExceptionHandler
Definition
InMemoryHybridMessageBus.cs:58
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus._subscriptions
readonly ConcurrentDictionary< Type, SubscriptionBucket > _subscriptions
Definition
InMemoryHybridMessageBus.cs:29
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.SubscriptionBucket
Definition
InMemoryHybridMessageBus.cs:297
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.SubscriptionBucket.Remove
void Remove(Subscription subscription)
Definition
InMemoryHybridMessageBus.cs:395
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.SubscriptionBucket._closed
bool _closed
Definition
InMemoryHybridMessageBus.cs:315
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.SubscriptionBucket._subscriptions
readonly List< Subscription > _subscriptions
Definition
InMemoryHybridMessageBus.cs:306
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.SubscriptionBucket.TryCloseIfEmpty
bool TryCloseIfEmpty()
Definition
InMemoryHybridMessageBus.cs:419
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.SubscriptionBucket.CreateSnapshot
Subscription[] CreateSnapshot()
Definition
InMemoryHybridMessageBus.cs:371
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.SubscriptionBucket.TryAdd
bool TryAdd(Subscription subscription)
Definition
InMemoryHybridMessageBus.cs:341
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.Subscription
Definition
InMemoryHybridMessageBus.cs:443
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.Subscription.IsDisposed
bool IsDisposed
Definition
InMemoryHybridMessageBus.cs:541
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.Subscription._unsubscribe
readonly Action< Subscription > _unsubscribe
Definition
InMemoryHybridMessageBus.cs:452
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.Subscription.Subscription
Subscription(Type messageType, object handler, Action< Subscription > unsubscribe)
Definition
InMemoryHybridMessageBus.cs:503
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.Subscription.Handler
object Handler
Definition
InMemoryHybridMessageBus.cs:531
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.Subscription.MessageType
Type MessageType
Definition
InMemoryHybridMessageBus.cs:521
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.Subscription._disposed
volatile bool _disposed
Definition
InMemoryHybridMessageBus.cs:461
Dreamine.Hybrid.Messaging.InMemoryHybridMessageBus.Subscription.Dispose
void Dispose()
Definition
InMemoryHybridMessageBus.cs:551
Dreamine.Hybrid.Messaging.NullHybridMessageBusExceptionHandler
Definition
NullHybridMessageBusExceptionHandler.cs:15
Dreamine.Hybrid.Messaging.NullHybridMessageBusExceptionHandler.Instance
static readonly NullHybridMessageBusExceptionHandler Instance
Definition
NullHybridMessageBusExceptionHandler.cs:24
Messaging
InMemoryHybridMessageBus.cs
다음에 의해 생성됨 :
1.17.0