17
17
18
18
namespace SymphonyOSS . RestApiClient . Api . AgentApi
19
19
{
20
- using System ;
21
- using System . Collections . Generic ;
22
20
using System . Diagnostics ;
23
- using System . Threading . Tasks ;
24
21
using Authentication ;
25
- using Generated . Json ;
26
22
using Generated . OpenApi . AgentApi . Client ;
27
23
using Generated . OpenApi . AgentApi . Model ;
28
24
@@ -31,25 +27,12 @@ namespace SymphonyOSS.RestApiClient.Api.AgentApi
31
27
/// Encapsulates <see cref="Generated.OpenApi.AgentApi.Api.DatafeedApi"/>,
32
28
/// adding authentication token management and a custom execution strategy.
33
29
/// </summary>
34
- public class DatafeedApi
30
+ public class DatafeedApi : AbstractDatafeedApi
35
31
{
36
32
private static readonly TraceSource TraceSource = new TraceSource ( "SymphonyOSS.RestApiClient" ) ;
37
33
38
34
private readonly Generated . OpenApi . AgentApi . Api . IDatafeedApi _datafeedApi ;
39
35
40
- private readonly IAuthTokens _authTokens ;
41
-
42
- private readonly IApiExecutor _apiExecutor ;
43
-
44
- private readonly Dictionary < EventHandler < MessageEventArgs > , Task > _tasks = new Dictionary < EventHandler < MessageEventArgs > , Task > ( ) ;
45
-
46
- private volatile bool _shouldStop ;
47
-
48
- static DatafeedApi ( )
49
- {
50
- JsonSubtypeConverter . Register ( typeof ( V2Message ) ) ;
51
- }
52
-
53
36
/// <summary>
54
37
/// Initializes a new instance of the <see cref="DatafeedApi" /> class.
55
38
/// See <see cref="Factories.AgentApiFactory"/> for conveniently constructing
@@ -58,111 +41,40 @@ static DatafeedApi()
58
41
/// <param name="authTokens">Authentication tokens.</param>
59
42
/// <param name="configuration">Api configuration.</param>
60
43
/// <param name="apiExecutor">Execution strategy.</param>
61
- public DatafeedApi ( IAuthTokens authTokens , Configuration configuration , IApiExecutor apiExecutor )
44
+ public DatafeedApi ( IAuthTokens authTokens , Configuration configuration , IApiExecutor apiExecutor ) : base ( authTokens , apiExecutor )
62
45
{
63
46
_datafeedApi = new Generated . OpenApi . AgentApi . Api . DatafeedApi ( configuration ) ;
64
- _authTokens = authTokens ;
65
- _apiExecutor = apiExecutor ;
66
- }
67
-
68
- private event EventHandler < MessageEventArgs > _onMessage ;
69
- public event EventHandler < MessageEventArgs > OnMessage
70
- {
71
- add
72
- {
73
- _onMessage += value ;
74
- }
75
- remove
76
- {
77
- _onMessage -= value ;
78
- lock ( _tasks )
79
- {
80
- _tasks . Remove ( value ) ;
81
- }
82
- }
83
47
}
84
48
85
49
/// <summary>
86
50
/// Starts listening, notifying event handlers about incoming messages. Blocks
87
- /// until <see cref="Stop"/> is invoked.
51
+ /// until <see cref="AbstractDatafeedApi. Stop"/> is invoked.
88
52
/// </summary>
89
53
public void Listen ( )
90
54
{
91
- _shouldStop = false ;
55
+ ShouldStop = false ;
92
56
var datafeed = CreateDatafeed ( ) ;
93
- while ( ! _shouldStop )
57
+ while ( ! ShouldStop )
94
58
{
95
59
var messageList = ReadDatafeed ( ref datafeed ) ;
96
- if ( _shouldStop )
60
+ if ( ShouldStop )
97
61
{
98
62
// Don't process messages if the user has stopped listening.
99
63
break ;
100
64
}
101
65
102
- if ( messageList == null || _onMessage == null )
103
- {
104
- continue ;
105
- }
106
-
107
- foreach ( var eventHandler in _onMessage . GetInvocationList ( ) )
108
- {
109
- NotifyAsync ( ( EventHandler < MessageEventArgs > ) eventHandler , messageList ) ;
110
- }
111
- }
112
- }
113
-
114
- /// <summary>
115
- /// Requests that <see cref="Listen"/> should stop blocking and return control
116
- /// to the calling thread. Calling <see cref="Stop"/> will not immediately return
117
- /// control, but wait for the current outstanding request to complete.
118
- /// </summary>
119
- public void Stop ( )
120
- {
121
- _shouldStop = true ;
122
- }
123
-
124
- private async void NotifyAsync ( EventHandler < MessageEventArgs > messageEventHandler , V2MessageList messageList )
125
- {
126
- // Notify each handler in a separate task, maintaining the order of messages in the list, and
127
- // get back to reading the data feed again without waiting for listeners to process messages.
128
- Task task ;
129
- if ( _tasks . TryGetValue ( messageEventHandler , out task ) )
130
- {
131
- await task ;
132
- }
133
- _tasks [ messageEventHandler ] = Task . Run ( ( ) => Notify ( messageEventHandler , messageList ) ) ;
134
- }
135
-
136
- private void Notify ( EventHandler < MessageEventArgs > messageEventHandler , V2MessageList messageList )
137
- {
138
- foreach ( var message in messageList )
139
- {
140
- TraceSource . TraceEvent (
141
- TraceEventType . Verbose , 0 ,
142
- "Notifying listener about message with ID \" {0}\" in stream \" {1}\" " ,
143
- ( message as V2Message ) ? . Id , ( message as V2Message ) ? . StreamId ) ;
144
- try
145
- {
146
- messageEventHandler . Invoke ( this , new MessageEventArgs ( message ) ) ;
147
- }
148
- catch ( Exception e )
149
- {
150
- TraceSource . TraceEvent (
151
- TraceEventType . Error , 0 ,
152
- "Unhandled exception caught when notifying listener about message with ID \" {0}\" : {1}" ,
153
- message . Id , e ) ;
154
- }
66
+ ProcessMessageList ( messageList ) ;
155
67
}
156
68
}
157
69
158
70
private Datafeed CreateDatafeed ( )
159
71
{
160
- return _apiExecutor . Execute ( _datafeedApi . V1DatafeedCreatePost , _authTokens . SessionToken , _authTokens . KeyManagerToken ) ;
72
+ return ApiExecutor . Execute ( _datafeedApi . V1DatafeedCreatePost , AuthTokens . SessionToken , AuthTokens . KeyManagerToken ) ;
161
73
}
162
74
163
75
private V2MessageList ReadDatafeed ( string id , int ? maxMessages = null )
164
76
{
165
- return _apiExecutor . Execute ( _datafeedApi . V2DatafeedIdReadGet , id , _authTokens . SessionToken , _authTokens . KeyManagerToken , maxMessages ) ;
77
+ return ApiExecutor . Execute ( _datafeedApi . V2DatafeedIdReadGet , id , AuthTokens . SessionToken , AuthTokens . KeyManagerToken , maxMessages ) ;
166
78
}
167
79
168
80
private V2MessageList ReadDatafeed ( ref Datafeed datafeed , int ? maxMessages = null )
0 commit comments