Skip to content

Commit c4e8e2b

Browse files
committed
Revert "tmp"
This reverts commit 2edaf9e.
1 parent 3819efd commit c4e8e2b

File tree

2 files changed

+126
-180
lines changed

2 files changed

+126
-180
lines changed

src/Components/Server/src/ComponentHub.cs

Lines changed: 97 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -209,42 +209,33 @@ public async Task UpdateRootComponents(string serializedComponentOperations, str
209209
_ = circuitHost.UpdateRootComponents(operations, store, Context.ConnectionAborted);
210210
}
211211

212-
public void ConnectCircuit(string circuitIdSecret)
212+
public async ValueTask<bool> ConnectCircuit(string circuitIdSecret)
213213
{
214214
// TryParseCircuitId will not throw.
215215
if (!_circuitIdFactory.TryParseCircuitId(circuitIdSecret, out var circuitId))
216216
{
217217
// Invalid id.
218218
Log.InvalidCircuitId(_logger, circuitIdSecret);
219-
_ = Clients.Caller.SendAsync("JS.EndConnectCircuit", false);
220-
return;
219+
return false;
221220
}
222221

223-
_ = ConnectCircuitCore(circuitId);
224-
225-
return;
226-
227-
async Task ConnectCircuitCore(CircuitId circuitId)
222+
// ConnectAsync will not throw.
223+
var circuitHost = await _circuitRegistry.ConnectAsync(
224+
circuitId,
225+
Clients.Caller,
226+
Context.ConnectionId,
227+
Context.ConnectionAborted);
228+
if (circuitHost != null)
228229
{
229-
// ConnectAsync will not throw.
230-
var circuitHost = await _circuitRegistry.ConnectAsync(
231-
circuitId,
232-
Clients.Caller,
233-
Context.ConnectionId,
234-
Context.ConnectionAborted);
235-
if (circuitHost != null)
236-
{
237-
_circuitHandleRegistry.SetCircuit(Context.Items, CircuitKey, circuitHost);
238-
circuitHost.SetCircuitUser(Context.User);
239-
circuitHost.SendPendingBatches();
240-
_ = Clients.Caller.SendAsync("JS.EndConnectCircuit", true);
241-
return;
242-
}
243-
244-
// If we get here the circuit does not exist anymore. This is something that's valid for a client to
245-
// recover from, and the client is not holding any resources right now other than the connection.
246-
_ = Clients.Caller.SendAsync("JS.EndConnectCircuit", false);
230+
_circuitHandleRegistry.SetCircuit(Context.Items, CircuitKey, circuitHost);
231+
circuitHost.SetCircuitUser(Context.User);
232+
circuitHost.SendPendingBatches();
233+
return true;
247234
}
235+
236+
// If we get here the circuit does not exist anymore. This is something that's valid for a client to
237+
// recover from, and the client is not holding any resources right now other than the connection.
238+
return false;
248239
}
249240

250241
// This method drives the resumption of a circuit that has been previously paused and ejected out of memory.
@@ -275,10 +266,10 @@ async Task ConnectCircuitCore(CircuitId circuitId)
275266
// * B might complete the handshake and then the circuit will resume on B.
276267
// * A deletes the state before B is able to read it. Then "resumption" fails, as the circuit state is gone.
277268

278-
// On the server we are going to have a public method on Circuit.cs to trigger pausing a circuit from the server
279-
// that returns the root components and application state as strings data-protected by the data protection provider.
280-
// Those can be then passed to this method for resuming the circuit.
281-
public async void ResumeCircuit(
269+
// On the server we are going to have a public method on Circuit.cs to trigger pausing a circuit from the server
270+
// that returns the root components and application state as strings data-protected by the data protection provider.
271+
// Those can be then passed to this method for resuming the circuit.
272+
public async ValueTask<string> ResumeCircuit(
282273
string circuitIdSecret,
283274
string baseUri,
284275
string uri,
@@ -290,8 +281,7 @@ public async void ResumeCircuit(
290281
{
291282
// Invalid id.
292283
Log.ResumeInvalidCircuitId(_logger, circuitIdSecret);
293-
_ = Clients.Caller.SendAsync("JS.EndResumeCircuit", (string)null, Context.ConnectionAborted);
294-
return;
284+
return null;
295285
}
296286

297287
var circuitHost = _circuitHandleRegistry.GetCircuit(Context.Items, CircuitKey);
@@ -301,9 +291,8 @@ public async void ResumeCircuit(
301291
// We can reject this and terminate the connection.
302292
Log.CircuitAlreadyInitialized(_logger, circuitHost.CircuitId);
303293
await NotifyClientError(Clients.Caller, $"The circuit host '{circuitHost.CircuitId}' has already been initialized.");
304-
_ = Clients.Caller.SendAsync("JS.EndResumeCircuit", (string)null, Context.ConnectionAborted);
305294
Context.Abort();
306-
return;
295+
return null;
307296
}
308297

309298
if (baseUri == null ||
@@ -318,100 +307,92 @@ public async void ResumeCircuit(
318307
// We can reject this and terminate the connection.
319308
Log.InvalidInputData(_logger);
320309
await NotifyClientError(Clients.Caller, "The uris provided are invalid.");
321-
_ = Clients.Caller.SendAsync("JS.EndResumeCircuit", (string)null, Context.ConnectionAborted);
322310
Context.Abort();
323-
return;
311+
return null;
324312
}
325313

326-
_ = ResumeCircuitCore(baseUri, uri, rootComponents, applicationState, circuitId);
327-
return;
328-
329-
static bool RootComponentIsEmpty(string rootComponents) =>
330-
string.IsNullOrEmpty(rootComponents) || rootComponents == "[]";
331-
332-
async Task ResumeCircuitCore(string baseUri, string uri, string rootComponents, string applicationState, CircuitId circuitId)
314+
PersistedCircuitState? persistedCircuitState;
315+
if (RootComponentIsEmpty(rootComponents) && string.IsNullOrEmpty(applicationState))
333316
{
334-
PersistedCircuitState? persistedCircuitState;
335-
if (RootComponentIsEmpty(rootComponents) && string.IsNullOrEmpty(applicationState))
336-
{
337-
var resumeTask = _circuitPersistenceManager.ResumeCircuitAsync(circuitId, Context.ConnectionAborted);
338-
persistedCircuitState = await resumeTask;
339-
if (persistedCircuitState == null)
340-
{
341-
Log.InvalidInputData(_logger);
342-
await NotifyClientError(Clients.Caller, "The circuit state could not be retrieved. It may have been deleted or expired.");
343-
Context.Abort();
344-
return;
345-
}
346-
}
347-
else if (!RootComponentIsEmpty(rootComponents) && !string.IsNullOrEmpty(applicationState))
348-
{
349-
persistedCircuitState = _circuitPersistenceManager.FromProtectedState(rootComponents, applicationState);
350-
if (persistedCircuitState == null)
351-
{
352-
// If we couldn't deserialize the persisted state, signal that.
353-
Log.InvalidInputData(_logger);
354-
await NotifyClientError(Clients.Caller, "The root components or application state provided are invalid.");
355-
Context.Abort();
356-
return;
357-
}
358-
}
359-
else
317+
persistedCircuitState = await _circuitPersistenceManager.ResumeCircuitAsync(circuitId, Context.ConnectionAborted);
318+
if (persistedCircuitState == null)
360319
{
361320
Log.InvalidInputData(_logger);
362-
await NotifyClientError(
363-
Clients.Caller,
364-
RootComponentIsEmpty(rootComponents) ?
365-
"The root components provided are invalid." :
366-
"The application state provided is invalid."
367-
);
321+
await NotifyClientError(Clients.Caller, "The circuit state could not be retrieved. It may have been deleted or expired.");
368322
Context.Abort();
369-
return;
323+
return null;
370324
}
371-
372-
try
373-
{
374-
var circuitClient = new CircuitClientProxy(Clients.Caller, Context.ConnectionId);
375-
var resourceCollection = Context.GetHttpContext().GetEndpoint()?.Metadata.GetMetadata<ResourceAssetCollection>();
376-
var circuitHost = await _circuitFactory.CreateCircuitHostAsync(
377-
[],
378-
circuitClient,
379-
baseUri,
380-
uri,
381-
Context.User,
382-
store: null,
383-
resourceCollection);
384-
385-
// Fire-and-forget the initialization process, because we can't block the
386-
// SignalR message loop (we'd get a deadlock if any of the initialization
387-
// logic relied on receiving a subsequent message from SignalR), and it will
388-
// take care of its own errors anyway.
389-
await circuitHost.InitializeAsync(store: null, _httpContext, Context.ConnectionAborted);
390-
391-
circuitHost.AttachPersistedState(persistedCircuitState);
392-
393-
// It's safe to *publish* the circuit now because nothing will be able
394-
// to run inside it until after InitializeAsync completes.
395-
_circuitRegistry.Register(circuitHost);
396-
_circuitHandleRegistry.SetCircuit(Context.Items, CircuitKey, circuitHost);
397-
398-
// Returning the secret here so the client can reconnect.
399-
//
400-
// Logging the secret and circuit ID here so we can associate them with just logs (if TRACE level is on).
401-
Log.CreatedCircuit(_logger, circuitHost.CircuitId, circuitHost.CircuitId.Secret, Context.ConnectionId);
402-
403-
await Clients.Caller.SendAsync("JS.EndResumeCircuit", circuitHost.CircuitId.Secret, Context.ConnectionAborted);
404-
}
405-
catch (Exception ex)
325+
}
326+
else if (!RootComponentIsEmpty(rootComponents) && !string.IsNullOrEmpty(applicationState))
327+
{
328+
persistedCircuitState = _circuitPersistenceManager.FromProtectedState(rootComponents, applicationState);
329+
if (persistedCircuitState == null)
406330
{
407-
// If the circuit fails to initialize synchronously we can notify the client immediately
408-
// and shut down the connection.
409-
Log.CircuitInitializationFailed(_logger, ex);
410-
await NotifyClientError(Clients.Caller, "The circuit failed to initialize.");
331+
// If we couldn't deserialize the persisted state, signal that.
332+
Log.InvalidInputData(_logger);
333+
await NotifyClientError(Clients.Caller, "The root components or application state provided are invalid.");
411334
Context.Abort();
412-
return;
335+
return null;
413336
}
414337
}
338+
else
339+
{
340+
Log.InvalidInputData(_logger);
341+
await NotifyClientError(
342+
Clients.Caller,
343+
RootComponentIsEmpty(rootComponents) ?
344+
"The root components provided are invalid." :
345+
"The application state provided is invalid."
346+
);
347+
Context.Abort();
348+
return null;
349+
}
350+
351+
try
352+
{
353+
var circuitClient = new CircuitClientProxy(Clients.Caller, Context.ConnectionId);
354+
var resourceCollection = Context.GetHttpContext().GetEndpoint()?.Metadata.GetMetadata<ResourceAssetCollection>();
355+
circuitHost = await _circuitFactory.CreateCircuitHostAsync(
356+
[],
357+
circuitClient,
358+
baseUri,
359+
uri,
360+
Context.User,
361+
store: null,
362+
resourceCollection);
363+
364+
// Fire-and-forget the initialization process, because we can't block the
365+
// SignalR message loop (we'd get a deadlock if any of the initialization
366+
// logic relied on receiving a subsequent message from SignalR), and it will
367+
// take care of its own errors anyway.
368+
_ = circuitHost.InitializeAsync(store: null, _httpContext, Context.ConnectionAborted);
369+
370+
circuitHost.AttachPersistedState(persistedCircuitState);
371+
372+
// It's safe to *publish* the circuit now because nothing will be able
373+
// to run inside it until after InitializeAsync completes.
374+
_circuitRegistry.Register(circuitHost);
375+
_circuitHandleRegistry.SetCircuit(Context.Items, CircuitKey, circuitHost);
376+
377+
// Returning the secret here so the client can reconnect.
378+
//
379+
// Logging the secret and circuit ID here so we can associate them with just logs (if TRACE level is on).
380+
Log.CreatedCircuit(_logger, circuitHost.CircuitId, circuitHost.CircuitId.Secret, Context.ConnectionId);
381+
382+
return circuitHost.CircuitId.Secret;
383+
}
384+
catch (Exception ex)
385+
{
386+
// If the circuit fails to initialize synchronously we can notify the client immediately
387+
// and shut down the connection.
388+
Log.CircuitInitializationFailed(_logger, ex);
389+
await NotifyClientError(Clients.Caller, "The circuit failed to initialize.");
390+
Context.Abort();
391+
return null;
392+
}
393+
394+
static bool RootComponentIsEmpty(string rootComponents) =>
395+
string.IsNullOrEmpty(rootComponents) || rootComponents == "[]";
415396
}
416397

417398
// Client initiated pauses work as follows:

0 commit comments

Comments
 (0)