Skip to content

Commit f4dd720

Browse files
authored
TokenSourceComponent: switch from async/await to coroutine (#275)
* TokenSourceComponent: switch from async/await to coroutine Aligns TokenSourceComponent with the rest of the SDK, which uses CustomYieldInstruction-based coroutines. FetchConnectionDetails now returns a FetchConnectionDetailsInstruction; the underlying ITokenSource interfaces stay Task-based since HttpClient is async-native. Updates the Meet sample to yield on the instruction. * Generalize Task->coroutine adapter as TaskYieldInstruction<T> Replaces the one-off FetchConnectionDetailsInstruction with a generic TaskYieldInstruction<T> in Internal/, so any future Task-returning API can be exposed as a coroutine without a new wrapper class.
1 parent bc52ffb commit f4dd720

3 files changed

Lines changed: 55 additions & 12 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
4+
namespace LiveKit
5+
{
6+
/// <summary>
7+
/// Adapts a <see cref="Task{TResult}"/> to a coroutine-friendly <see cref="YieldInstruction"/>.
8+
/// Yield on it from a coroutine, then read <see cref="Result"/> on success or
9+
/// <see cref="Exception"/> when <see cref="YieldInstruction.IsError"/> is true.
10+
/// </summary>
11+
public sealed class TaskYieldInstruction<T> : YieldInstruction
12+
{
13+
public T Result { get; private set; }
14+
public Exception Exception { get; private set; }
15+
16+
internal TaskYieldInstruction(Task<T> task)
17+
{
18+
// Continuation may run on a thread-pool thread; the volatile IsDone/IsError fields in
19+
// the base class give the polling main thread acquire semantics for Result/Exception.
20+
task.ContinueWith(t =>
21+
{
22+
if (t.IsFaulted)
23+
{
24+
Exception = t.Exception?.InnerException ?? t.Exception;
25+
IsError = true;
26+
}
27+
else if (t.IsCanceled)
28+
{
29+
IsError = true;
30+
}
31+
else
32+
{
33+
Result = t.Result;
34+
}
35+
IsDone = true;
36+
});
37+
}
38+
}
39+
}

Runtime/Scripts/TokenSource/TokenSourceComponent.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class TokenSourceComponent : MonoBehaviour
2020
/// Fetches connection details using only the values on the asset-backed
2121
/// <see cref="TokenSourceComponentConfig"/>. Equivalent to <c>FetchConnectionDetails(null)</c>.
2222
/// </summary>
23-
public Task<ConnectionDetails> FetchConnectionDetails() => FetchConnectionDetails(null);
23+
public TaskYieldInstruction<ConnectionDetails> FetchConnectionDetails() => FetchConnectionDetails(null);
2424

2525
ITokenSource _tokenSource;
2626

@@ -56,22 +56,26 @@ public void Start()
5656
/// overrides the config value (empty strings are treated as unset and fall through to the config).
5757
/// Ignored for fixed token sources (<see cref="TokenSourceLiteral"/>, <see cref="TokenSourceCustom"/>).
5858
/// </summary>
59-
public async Task<ConnectionDetails> FetchConnectionDetails(TokenSourceFetchOptions? options)
59+
public TaskYieldInstruction<ConnectionDetails> FetchConnectionDetails(TokenSourceFetchOptions options)
6060
{
61+
Task<ConnectionDetails> task;
6162
switch (_tokenSource)
6263
{
6364
case ITokenSourceConfigurable configurableSource:
64-
return await configurableSource.FetchConnectionDetails(Coalesce(_config, options));
65-
65+
task = configurableSource.FetchConnectionDetails(Coalesce(_config, options));
66+
break;
67+
6668
case ITokenSourceFixed fixedSource:
6769
if (options != null)
6870
Debug.LogWarning("TokenSourceComponent uses a fixed config, so fetch options are ignored.");
69-
return await fixedSource.FetchConnectionDetails();
71+
task = fixedSource.FetchConnectionDetails();
72+
break;
7073

7174
default:
7275
throw new InvalidOperationException("Unknown token source type");
73-
}
74-
}
76+
}
77+
return new TaskYieldInstruction<ConnectionDetails>(task);
78+
}
7579

7680
private static TokenSourceFetchOptions Coalesce(TokenSourceComponentConfig config, TokenSourceFetchOptions? options)
7781
{

Samples~/Meet/Assets/Runtime/MeetManager.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,16 @@ private IEnumerator ConnectToRoom()
157157
{
158158
if (_room != null) yield break;
159159

160-
var connectionDetailsTask = _tokenSourceComponent.FetchConnectionDetails(new TokenSourceFetchOptions());
161-
yield return new WaitUntil(() => connectionDetailsTask.IsCompleted);
160+
var fetch = _tokenSourceComponent.FetchConnectionDetails(new TokenSourceFetchOptions());
161+
yield return fetch;
162162

163-
if (connectionDetailsTask.IsFaulted)
163+
if (fetch.IsError)
164164
{
165-
Debug.LogError($"Failed to fetch connection details: {connectionDetailsTask.Exception?.InnerException?.Message}");
165+
Debug.LogError($"Failed to fetch connection details: {fetch.Exception?.Message}");
166166
yield break;
167167
}
168168

169-
var details = connectionDetailsTask.Result;
169+
var details = fetch.Result;
170170

171171
_room = new Room();
172172
_room.TrackSubscribed += OnTrackSubscribed;

0 commit comments

Comments
 (0)