runOperationInServer method
Future<InternalAsklessResponseEntity>
runOperationInServer({
- required AbstractRequestCli data,
- bool neverTimeout = false,
- bool ifRequiresAuthenticationWaitForIt = true,
- required bool isPersevere(),
Does NOT wait for connection
Implementation
Future<InternalAsklessResponseEntity> runOperationInServer({required AbstractRequestCli data, bool neverTimeout = false, bool ifRequiresAuthenticationWaitForIt = true, required bool Function() isPersevere}) async {
bool isAfterAuthentication = getIt.get<AuthenticateService>().authStatus == AuthStatus.authenticated;
final completer = Completer<InternalAsklessResponseEntity>();
data.clientRequestId ??= '${REQUEST_PREFIX}_${randomAlphaNumeric(28)}';
// ignore: prefer_function_declarations_over_variables
final sendWhenConnected = (ConnectionDetails connection) async {
if (connection.status == ConnectionStatus.connected) {
if (isAfterAuthentication) {
await getIt.get<AuthenticateService>().waitForAuthentication(neverTimeout: false, isPersevere: () => false);
}
logger('Sending data to server...', level: Level.debug,);
ws.sinkAdd(map: data);
}
};
final _Request request = _Request(data, (response) {
getIt.get<ConnectionService>().removeOnConnectionChange(sendWhenConnected);
if (!completer.isCompleted){
completer.complete(response);
}
});
getIt.get<ConnectionService>().addOnConnectionChangeListener(sendWhenConnected, immediately: request.data.requestType != RequestType.CONFIGURE_CONNECTION, beforeOthersListeners: data.requestType == RequestType.CONFIGURE_CONNECTION || data.requestType == RequestType.AUTHENTICATE);
if (neverTimeout == false && connectionConfiguration.requestTimeoutInMs > 0) {
Future.delayed(Duration(milliseconds: connectionConfiguration.requestTimeoutInMs), () {
// _lockPendingRequestsList.synchronized(() async {
final remove = _pendingRequestsList.firstWhereOrNull((p) => p.data.clientRequestId == request.data.clientRequestId,);
if (remove != null) {
_pendingRequestsList.remove(remove);
request.onResponse(InternalAsklessResponseEntity(
clientRequestId: data.clientRequestId!,
error: AsklessError(code: AsklessErrorCode.noConnection, description: 'Request timed out')
));
logger('Your request (${data.requestType}) \"${data.getRoute() ?? ''}\" timed out, check if: \n\t1) Your server configuration is serving on ${serverUrl}\n\t2) Your device has connection with internet\n\t3) Your API route implementation calls context.success or context.error methods', level: Level.error);
}
});
// });
}
// await _lockPendingRequestsList.synchronized(() async {
if (ws.isReady == true){
await _addAsPending(request);
} else {
if (data.waitUntilGetServerConnection) {
await _addAsPending(request);
logger('Waiting connection to send message', level: Level.debug);
} else {
logger('You can\'t send this message while not connected', level: Level.debug);
request.onResponse(InternalAsklessResponseEntity(
clientRequestId: data.clientRequestId!,
error: AsklessError(description: 'Maybe de device has no internet or the server is offline', code: 'AsklessErrorCode.noConnection')
)
);
}
}
if (request.data.requestType == RequestType.CONFIGURE_CONNECTION) {
logger('Sending data to server...', level: Level.debug,);
ws.sinkAdd(map: data);
}
final response = await completer.future;
if (ifRequiresAuthenticationWaitForIt && response.error?.code == AsklessErrorCode.pendingAuthentication) {
logger("${request.data.getRoute() ?? ''}: requires authentication, waiting for it, OLD clientRequestId WAS ${request.data.clientRequestId}");
request.data.clientRequestId = '${REQUEST_PREFIX}_${randomAlphaNumeric(28)}';
logger("${request.data.getRoute() ?? ''}: NEW clientRequestId IS ${request.data.clientRequestId}, now it will wait for the authentication to finished...");
isAfterAuthentication = true;
if (getIt.get<AuthenticateService>().authStatus == AuthStatus.authenticated) {
logger("(waitForAuthentication, request_service.dart) Ops, this shouldn't happen, the App says it is authenticated but the server says is not authenticated", level: Level.error);
}
final authenticated = await getIt.get<AuthenticateService>().waitForAuthentication(
neverTimeout: neverTimeout,
isPersevere: isPersevere,
requestType: request.data.requestType,
route: request.data.getRoute()
);
logger("...${request.data.getRoute() ?? ''}: finished waiting for authentication");
if (authenticated) {
logger("${request.data.getRoute() ?? ''}: performing operation AGAIN after authenticated");
return runOperationInServer(data: data, neverTimeout: neverTimeout, isPersevere: isPersevere);
} else {
logger("${request.data.getRoute() ?? ''}: authentication failed, so the request failed as well");
}
}
final remove = _pendingRequestsList.firstWhereOrNull((p) => p.data.clientRequestId == request.data.clientRequestId,);
if (remove != null) {
_pendingRequestsList.remove(remove);
}
return response;
}