private void HandleApiResponse(JToken data) { if (data == null && data.Children().Count() != 2) { return; } var idToken = data.SelectToken("id"); if (idToken == null) { throw new Exception("response id not found."); } string id = idToken.ToObject <string>(); TaskCompletionSource <JToken> openTask; if (!OpenTasks.TryGetValue(id, out openTask)) { return; } OpenTasks.Remove(id); OpenTaskTimes.Remove(id); openTask.SetResult(data.SelectToken("result")); }
protected override void HandleApiResponse(IEnumerable <object> args) { var data = args.Cast <JToken>().First(); if (data == null && data.Children().Count() != 2) { return; } var idToken = data.SelectToken("id"); if (idToken == null) { throw new Exception("response id not found."); } string id = idToken.ToObject <string>(); OpenTask openTask; if (!OpenTasks.TryGetValue(id, out openTask)) { return; } OpenTasks.Remove(id); openTask.PromiseTask.SetResult(data.SelectToken("result")); }
public async Task <JToken> SendApiRequest(Request request) { if (request.Type == "identityFromPermissions" && !Paired) { return(false); } await Pair(); if (!Paired) { throw new Exception("The user did not allow this app to connect to their Scatter"); } var tcs = new TaskCompletionSource <JToken>(); request.Id = UtilsHelper.RandomNumber(24); request.Appkey = StorageProvider.GetAppkey(); request.Nonce = StorageProvider.GetNonce() ?? ""; var nextNonce = UtilsHelper.RandomNumberBytes(); request.NextNonce = UtilsHelper.ByteArrayToHexString(Sha256Manager.GetHash(nextNonce)); StorageProvider.SetNonce(UtilsHelper.ByteArrayToHexString(nextNonce)); OpenTasks.Add(request.Id, tcs); OpenTaskTimes.Add(request.Id, DateTime.Now); await Send("api", new { data = request, plugin = AppName }); return(await tcs.Task); }
protected void HandlePairedResponse(bool?paired) { Paired = paired.GetValueOrDefault(); if (Paired) { var storedAppKey = StorageProvider.GetAppkey(); string hashed = storedAppKey.StartsWith("appkey:") ? UtilsHelper.ByteArrayToHexString(Sha256Manager.GetHash(Encoding.UTF8.GetBytes(storedAppKey))) : storedAppKey; if (string.IsNullOrWhiteSpace(storedAppKey) || storedAppKey != hashed) { StorageProvider.SetAppkey(hashed); } } OpenTask openTask; if (!OpenTasks.TryGetValue(PairOpenId, out openTask)) { return; } openTask.PromiseTask.SetResult(Paired); openTask.TaskTimeoutMS = int.MaxValue; }
/// <summary> /// Pair appication to registered applications in scatter /// </summary> /// <param name="passthrough">pass through rekey process</param> /// <param name="timeout">set response timeout that overrides the default one</param> /// <returns></returns> public async Task Pair(bool passthrough = false, int?timeout = null) { var pairOpenTask = new TaskCompletionSource <object>(); var openTask = new OpenTask() { PromiseTask = pairOpenTask, TaskRequestTime = DateTime.Now, TaskTimeoutMS = timeout.HasValue ? timeout.Value : TimeoutMS }; if (OpenTasks.ContainsKey(PairOpenId)) { OpenTasks[PairOpenId] = openTask; } else { OpenTasks.Add(PairOpenId, openTask); } await SockIO.EmitAsync("pair", new RequestWrapper() { data = new PairRequest() { appkey = StorageProvider.GetAppkey(), passthrough = passthrough, origin = AppName }, plugin = AppName }); await pairOpenTask.Task; }
private void TimeoutOpenTasksCheck() { while (Socket.State == WebSocketState.Open) { var now = DateTime.Now; int count = 0; foreach (var ttKey in OpenTaskTimes.Keys) { if ((now - OpenTaskTimes[ttKey]).TotalMilliseconds >= TimeoutMS) { TaskCompletionSource <JToken> openTask = OpenTasks[ttKey]; OpenTasks.Remove(ttKey); OpenTaskTimes.Remove(ttKey); openTask.SetResult(JToken.FromObject(new ApiError() { Code = "0", IsError = "true", Message = "Request timeout." })); } //sleep checking each 10 requests if ((count % 10) == 0) { Thread.Sleep(1000); } count++; } } }
public void RefreshOpenTasks() { if (_settings.ServerSettings.JsonDirectory == null) { throw new DistSimException("Jsondirectory was null"); } if (_settings.ServerSettings.JsonDirectory.Count == 0) { throw new DistSimException("Jsondirectory was empty"); } foreach (string singledir in _settings.ServerSettings.JsonDirectory) { if (OpenTasks.Count > 1000) { break; } DirectoryInfo di = new DirectoryInfo(singledir); if (!di.Exists) { di.Create(); Thread.Sleep(100); } var files = di.GetFiles("*.json"); var activeFiles = ActiveTasks.Select(x => x.OriginalJsonFilePath).ToList(); var openTaskFiles = OpenTasks.Select(x => x.OriginalJsonFilePath).ToList(); foreach (var fileInfo in files) { if (activeFiles.Contains(fileInfo.FullName)) { _logger.Info("Currently processing " + fileInfo.Name, _threadId); continue; } if (openTaskFiles.Contains(fileInfo.FullName)) { _logger.Info("Currently in queue " + fileInfo.Name, _threadId); continue; } ServerExecutionTask set = new ServerExecutionTask(fileInfo.FullName, fileInfo.Name, Guid.NewGuid().ToString()); OpenTasks.Enqueue(set); _logger.Info("Created a job for " + fileInfo.Name, _threadId); if (OpenTasks.Count > 1000) { break; } } } }
protected IEnumerator TimeoutOpenTasksCheck() { while (SockIO.GetState() == WebSocketState.Open) { var now = DateTime.Now; int count = 0; List <string> toRemoveKeys = new List <string>(); foreach (var key in OpenTasks.Keys.ToList()) { OpenTask openTask; if (!OpenTasks.TryGetValue(key, out openTask)) { continue; } if ((now - openTask.TaskRequestTime).TotalMilliseconds >= openTask.TaskTimeoutMS) { toRemoveKeys.Add(key); } //sleep checking each 10 requests if ((count % ScatterConstants.OPEN_TASK_NR_CHECK) == 0) { count = 0; yield return(WaitForOpenTasksCheck(ScatterConstants.OPEN_TASK_CHECK_INTERVAL_SECS)); } count++; } foreach (var key in toRemoveKeys) { OpenTask openTask; if (!OpenTasks.TryGetValue(key, out openTask)) { continue; } OpenTasks.Remove(key); openTask.PromiseTask.SetResult(BuildApiError()); } yield return(WaitForOpenTasksCheck(ScatterConstants.OPEN_TASK_CHECK_INTERVAL_SECS)); } }
/// <summary> /// Send api request to scatter /// </summary> /// <typeparam name="TRequest">Request type param</typeparam> /// <typeparam name="TReturn">Return type param</typeparam> /// <param name="request">Request object</param> /// <param name="timeout">set response timeout that overrides the default one</param> /// <returns></returns> public async Task <TReturn> SendApiRequest <TRequest, TReturn>(Request <TRequest> request, int?timeout = null) { if (request.type == "identityFromPermissions" && !Paired) { return(default(TReturn)); } await Pair(); if (!Paired) { throw new Exception("The user did not allow this app to connect to their Scatter"); } var tcs = new TaskCompletionSource <object>(); do { request.id = UtilsHelper.RandomNumber(24); }while (OpenTasks.ContainsKey(request.id)); request.appkey = StorageProvider.GetAppkey(); request.nonce = StorageProvider.GetNonce() ?? ""; var nextNonce = UtilsHelper.RandomNumberBytes(); request.nextNonce = UtilsHelper.ByteArrayToHexString(Sha256Manager.GetHash(nextNonce)); StorageProvider.SetNonce(UtilsHelper.ByteArrayToHexString(nextNonce)); OpenTasks.Add(request.id, new OpenTask() { PromiseTask = tcs, TaskRequestTime = DateTime.Now, TaskTimeoutMS = timeout.HasValue ? timeout.Value : TimeoutMS }); await SockIO.EmitAsync("api", new RequestWrapper() { data = request, plugin = AppName }); return(BuildApiResponse <TReturn>(await tcs.Task)); }