-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integration of js-rpc timeout and middleware changes to fix Auth Provider timeout issue #589
Conversation
Would this actually solve the problem? Maybe it's better to link to PK CLI to just try the authenticate command? |
63b1178
to
afb4bc0
Compare
This problem is more complex than it first seemed. The root issue is :-
So therefore, the only possible solution right now is to alter timeout while Currently exploring other possible solutions but I am fairly certain that this is the only solution here to fix the issue, as the core issue is the fact that RPC times out in exactly 15000ms, which isn't nearly enough time to comfortably authenticate github or other providers. |
To fix this properly there needs to be some changes to the handlers, callers and possible RPC.
Ultimately we need to be able to
You'll need to explore the If we do need to make changes to the |
Alright, I'll look into the RPC code. Thanks for the reply. |
Please flesh out the spec in the OP @addievo |
This requires changes to the |
It's in the github events: MatrixAI/js-rpc#47 |
So this PR grows in complexity by the day.
a. When RPC times out, theres a particular error it throws: > ts-node src/polykey.ts -np ./tmp/nodeA identities authenticate github.com
url https://github.com/login/device
userCode 5FC2-254D
ErrorRPCTimedOut: RPC has timed out b. Whereas with the normal timeout, it throws a specific error as so: > ts-node src/polykey.ts -np ./tmp/nodeA identities authenticate github.com
url https://github.com/login/device
userCode 5FC2-254D
ErrorRPCTimedOut: RPC has timed out
// Promise.race does not cancel unfinished promises
// the finished condition variable is needed to stop the pollAccessToken process
// the pollTimer is needed to stop the pollTimerP
let pollTimedOut = false;
let pollTimer;
const pollTimerP = new Promise<void>((r) => {
pollTimer = setTimeout(() => {
pollTimedOut = true;
r();
}, timeout);
});
const that = this;
const pollAccessToken = async () => {
const payload = new URLSearchParams();
payload.set('grant_type', 'urn:ietf:params:oauth:grant-type:device_code');
payload.set('client_id', that.clientId);
payload.set('device_code', deviceCode);
const request = new Request(
'https://github.com/login/oauth/access_token',
{
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
},
body: payload.toString(),
},
);
while (true) {
if (pollTimedOut) {
this.logger.info('Poll has timed out');
return;
}
const response = await fetch(request);
if (!response.ok) {
throw new identitiesErrors.ErrorProviderAuthentication(
`Provider responded with ${response.status} ${response.statusText}`,
);
}
let data;
try {
data = await response.json();
} catch (e) {
throw new identitiesErrors.ErrorProviderAuthentication(
'Provider access token response is not valid JSON',
{ cause: e },
);
}
if (data.error) {
if (data.error === 'authorization_pending') {
await utils.sleep(pollInterval);
continue;
} else if (data.error === 'slow_down') {
// Convert seconds to milliseconds
pollInterval = parseInt(data.get('interval') ?? '1') * 1000;
await utils.sleep(pollInterval);
continue;
}
throw new identitiesErrors.ErrorProviderAuthentication(
`Provider access token request responded with: ${data.error}`,
);
}
const providerToken = {
accessToken: data.access_token,
};
return providerToken;
}
};
let providerToken;
try {
providerToken = await Promise.race([pollAccessToken(), pollTimerP]);
} finally {
clearTimeout(pollTimer);
}
if (providerToken == null) {
throw new identitiesErrors.ErrorProviderAuthentication(
`Provider authentication flow timed out`,
);
} As this is where the specific error being thrown. I will investigate this further. The only solution working till now is changing the default timeout ( Also to add on this point further, lets assume the default timeout for the Maybe the rpc requires further changes to set the timeout to default after the rpc call is handled. |
No the solution needs to be simplified. You have to verify that call site timeouts override client timeouts and handler timeouts override server timeouts. Once that is verified then you have to understand that between client and server, the lowest timeout is chosen. Therefore you just first give sufficient time on both ends. Using both call site timeout and also handler timeout. This has nothing to do with the client timeout or server timeout. Afterwards any further fixes happens on the PK CLI command itself. Also the scope isn't increasing - the scope is the requirement. You're supposed to figure out what needs to be done for the requirement. |
This is blocked on MatrixAI/js-rpc#47 |
I'll be merging the |
MatrixAI/js-rpc#47 has been merged now and doing a release. When that Is done i'll look into finishing this. |
I think we're adding some extra fixes to this PR. Things that need to be changed
|
@tegefaulkes Cleaning up PR and adding tasks |
i think types like |
4f1469f
to
6899223
Compare
Looks good |
Nope, it doesn't look good. See comments above. |
Do we have any calls in the entire client service or agent service that uses this yet? I don't think so, but it is likely to be needed to provide push-flow abstractions over the network boundary. |
@amydevs earlier @addievo meantioned the I'm thinking was originally used to poll the GitHub API. Now with things like timed context, can we refactor that to push-down the timer context? That loop was PRE-invention of the timer contexts. And it seems it can be refactored to improve our system. Perhaps it is necessary to actually solve the github auth timeout in its entirety? |
…rom `src/client` to `@matrixai/rpc` chore: lintfix [ci-skip]
…arams` and `AgentRPCResponseResult` [ci-skip]
da3018d
to
e0523d0
Compare
…to be less confusing chore: bump `@matrixai/rpc` to `0.3.1` [ci-skip]
e0523d0
to
77d7fd7
Compare
this would mean that the abstract |
i don't think there are any places that need long-running calls at the moment |
Ok |
should be ready to merge |
Description
Provider Auth Timeouts
This PR makes the timeout for the Provider Authentication flow longer. The result of how short it is currently is that the
js-rpc
default timeout set insrc/config
:As the Provider Authentication flow utilises the
IdentitiesAuthenticate
handler inclient/handlers
, it will follow this timeout. So there needs to be a way to override the default timeout for theIdentitiesAuthenticate
handler only, without affecting any other handlers.Although the aforementioned comment specifies
This is currently not the case, as in js-rpc handler timeout is preferred, only if it is lesser than the default timeout, which is not the case in our desired scenario.
The solution is to make it so that the handler timeout overrides the default timeout set on the
RPCServer
, regardless of whether one is longer than the other.This has now been updated in the following PR:
MatrixAI/js-rpc#47
Moving
timeoutMiddleware
tojs-rpc
As per MatrixAI/js-rpc#42,
timeoutMiddleware
has been moved out, and is now a default middleware. This will mean thattimeoutMiddleware
will be applied everywhere.Updated Type Requirements of
js-rpc
Requestparams
and Responseresults
The updated types in
js-rpc
ofJSONRPCRequestMessage
,JSONRPCRequestNotification
andJSONRPCResponseResult
mean thatJSONRPCRequest*.params
andJSONRPCResponseResult.result
should now always be objects. This is so that metadata can always be appended to the params. Therefore, we need to make sure in Polykey that non-JSON-objects are never being passed asresult
s orparams
.Long-Running Streaming Calls
Due to Timeout changes, specifically that timeouts no longer after the first server-sent message, long-running streaming calls are now possible without setting timeouts to
Infinity
.Issues Fixed
timeoutMiddleware
and Removemetadata.authorization
forsrc/nodes/agent
Domain #572Tasks
js-rpc
to allow for override of default timeouttimeoutMiddleware
fromPolykey
.ClientRPCRequestParms
andClientRPCResponseResult
from client handlers.metadata.authorization
fromAgentRPCRequestParams
andAgentRPCResponseResult
Final checklist