示例#1
0
        public IHttpActionResult PutActiveRequest(int id, ActiveRequest activeRequest)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            if (id != activeRequest.ID)
            {
                return(BadRequest());
            }

            db.Entry(activeRequest).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!ActiveRequestExists(id))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }

            return(StatusCode(HttpStatusCode.NoContent));
        }
示例#2
0
        public IHttpActionResult PostActiveRequest(ActiveRequest activeRequest)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            db.ActiveRequests.Add(activeRequest);

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateException)
            {
                if (ActiveRequestExists(activeRequest.ID))
                {
                    return(Conflict());
                }
                else
                {
                    throw;
                }
            }

            return(CreatedAtRoute("DefaultApi", new { id = activeRequest.ID }, activeRequest));
        }
        public void ModifyActiveRequest(ActiveRequest newActiveRequest)
        {
            var activeRequest = data.ActiveRequests.Where(x => x.Id == newActiveRequest.Id).FirstOrDefault();

            if (activeRequest != null)
            {
                activeRequest = newActiveRequest;
                data.SaveChanges();
            }
        }
示例#4
0
        public IHttpActionResult GetActiveRequest(int id)
        {
            ActiveRequest activeRequest = db.ActiveRequests.Find(id);

            if (activeRequest == null)
            {
                return(NotFound());
            }

            return(Ok(activeRequest));
        }
示例#5
0
        public IHttpActionResult DeleteActiveRequest(int id)
        {
            ActiveRequest activeRequest = db.ActiveRequests.Find(id);

            if (activeRequest == null)
            {
                return(NotFound());
            }

            db.ActiveRequests.Remove(activeRequest);
            db.SaveChanges();

            return(Ok(activeRequest));
        }
示例#6
0
        private Task <SMPPMessage> _submitMessage(SMPPMessage message)
        {
            ActiveRequest sendingMessage = _activeRequests.AddMessage(message);

            sendingMessage.SendTask = _sendMessage(message);
            sendingMessage.SendTask.ContinueWith((task) =>
            {
                if (task.Status != TaskStatus.RanToCompletion)
                {
                    _activeRequests.CompleteError(sendingMessage, task.Exception);
                }
            });
            return(sendingMessage.TaskCompletion.Task);
        }
示例#7
0
 public void Active([FromBody] ActiveRequest activeRequest)
 {
     using (var client = new WebClient())
     {
         try
         {
             var json     = Newtonsoft.Json.JsonConvert.SerializeObject(activeRequest);
             var dataByte = System.Text.Encoding.UTF8.GetBytes(json);
             client.Headers[HttpRequestHeader.ContentType] = "application/json";
             dataByte = client.UploadData(this.svconfig.admindbip + "/api/OnSite/Active/", "POST", dataByte);
         }
         catch (Exception e)
         {
             throw new Exception(e.Message);
         }
     }
 }
示例#8
0
 private bool FindActiveRequest(EasyRequest easy, out IntPtr gcHandlePtr, out ActiveRequest activeRequest)
 {
     // We maintain an IntPtr=>ActiveRequest mapping, which makes it cheap to look-up by GCHandle ptr but
     // expensive to look up by EasyRequest.  If we find this becoming a bottleneck, we can add a reverse
     // map that stores the other direction as well.
     foreach (KeyValuePair<IntPtr, ActiveRequest> pair in _activeOperations)
     {
         if (pair.Value.Easy == easy)
         {
             gcHandlePtr = pair.Key;
             activeRequest = pair.Value;
             return true;
         }
     }
     gcHandlePtr = IntPtr.Zero;
     activeRequest = default(ActiveRequest);
     return false;
 }
示例#9
0
        /// <summary>
        /// 获取公众号或企业号的jsapi_tickets
        /// </summary>
        /// <returns>返回json数据</returns>
        public string GetJsApiTicketsJson()
        {
            string sJsApiTicketsJson = string.Empty;
            string sUrl = string.Empty;

            if (this._wxPlatType == WxPlatFormTypeEnum.QY)
            {
                sUrl = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket";
                sJsApiTicketsJson = ActiveRequest.SendRequest(this.GetEntityByAction(sUrl, "", null, "get"));
            }
            else if (this._wxPlatType == WxPlatFormTypeEnum.GZ)
            {
                sUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
                Dictionary <string, string> dictParams = new Dictionary <string, string>()
                {
                    { "type", "jsapi" }
                };
                sJsApiTicketsJson = ActiveRequest.SendRequest(this.GetEntityByAction(sUrl, "", dictParams, "get"));
            }
            return(sJsApiTicketsJson);
        }
示例#10
0
        public override bool GetPiece(int index, int begin, byte[] piece)
        {
            bool          isFind      = false;
            int           pieceLength = piece.Length;
            bool          doIHave;
            ActiveRequest newRequest = new ActiveRequest(index, begin, pieceLength);

            foreach (ActiveRequest request in requests)
            {
                if (request.Equals(newRequest))
                {
                    requests.Remove(request);
                    isFind = true;
                    break;
                }
            }

            if (!isFind)
            {
                return(false);
            }
            last = DateTime.Now;
            measure.UpdateRate(pieceLength);

            if (downloader.MeasureFunction != null)
            {
                downloader.MeasureFunction(pieceLength);
            }

            downloader.DownloadMeasure.UpdateRate(pieceLength);
            downloader.StorageWrapper.PieceCameIn(index, begin, piece);

            doIHave = downloader.StorageWrapper.DoIHave(index);
            if (doIHave)
            {
                downloader.PiecePicker.Complete(index);
            }
            this.FixDownload();
            return(doIHave);
        }
示例#11
0
 public void RemoveActiveRequest(ActiveRequest request)
 {
     data.ActiveRequests.Remove(request);
     data.SaveChanges();
 }
示例#12
0
            private void WorkerLoop()
            {
                Debug.Assert(!Monitor.IsEntered(_incomingRequests), "No locks should be held while invoking Process");
                Debug.Assert(_runningWorker != null && _runningWorker.Id == Task.CurrentId, "This is the worker, so it must be running");
                Debug.Assert(_wakeupRequestedPipeFd != null && !_wakeupRequestedPipeFd.IsInvalid, "Should have a valid pipe for wake ups");

                // Create the multi handle to use for this round of processing.  This one handle will be used
                // to service all easy requests currently available and all those that come in while
                // we're processing other requests.  Once the work quiesces and there are no more requests
                // to process, this multi handle will be released as the worker goes away.  The next
                // time a request arrives and a new worker is spun up, a new multi handle will be created.
                SafeCurlMultiHandle multiHandle = CreateAndConfigureMultiHandle();

                // Clear our active operations table.  This should already be clear, either because
                // all previous operations completed without unexpected exception, or in the case of an
                // unexpected exception we should have cleaned up gracefully anyway.  But just in case...
                Debug.Assert(_activeOperations.Count == 0, "We shouldn't have any active operations when starting processing.");
                _activeOperations.Clear();

                bool endingSuccessfully = false;
                try
                {
                    // Continue processing as long as there are any active operations
                    while (true)
                    {
                        // First handle any requests in the incoming requests queue.
                        while (true)
                        {
                            IncomingRequest request;
                            lock (_incomingRequests)
                            {
                                if (_incomingRequests.Count == 0) break;
                                request = _incomingRequests.Dequeue();
                            }
                            HandleIncomingRequest(multiHandle, request);
                        }

                        // If we have no active operations, we're done.
                        if (_activeOperations.Count == 0)
                        {
                            endingSuccessfully = true;
                            return;
                        }

                        // We have one or more active operations. Run any work that needs to be run.
                        ThrowIfCURLMError(Interop.Http.MultiPerform(multiHandle));

                        // Complete and remove any requests that have finished being processed.
                        CURLMSG message;
                        IntPtr easyHandle;
                        CURLcode result;
                        while (Interop.Http.MultiInfoRead(multiHandle, out message, out easyHandle, out result))
                        {
                            Debug.Assert(message == CURLMSG.CURLMSG_DONE, "CURLMSG_DONE is supposed to be the only message type");

                            if (message == CURLMSG.CURLMSG_DONE)
                            {
                                IntPtr gcHandlePtr;
                                CURLcode getInfoResult = Interop.Http.EasyGetInfoPointer(easyHandle, CURLINFO.CURLINFO_PRIVATE, out gcHandlePtr);
                                Debug.Assert(getInfoResult == CURLcode.CURLE_OK, "Failed to get info on a completing easy handle");
                                if (getInfoResult == CURLcode.CURLE_OK)
                                {
                                    ActiveRequest completedOperation;
                                    bool gotActiveOp = _activeOperations.TryGetValue(gcHandlePtr, out completedOperation);
                                    Debug.Assert(gotActiveOp, "Expected to find GCHandle ptr in active operations table");
                                    if (gotActiveOp)
                                    {
                                        DeactivateActiveRequest(multiHandle, completedOperation.Easy, gcHandlePtr, completedOperation.CancellationRegistration);
                                        FinishRequest(completedOperation.Easy, result);
                                    }
                                }
                            }
                        }

                        // Wait for more things to do.
                        bool isWakeupRequestedPipeActive;
                        bool isTimeout;
                        ThrowIfCURLMError(Interop.Http.MultiWait(multiHandle, _wakeupRequestedPipeFd, out isWakeupRequestedPipeActive, out isTimeout));
                        if (isWakeupRequestedPipeActive)
                        {
                            // We woke up (at least in part) because a wake-up was requested.  
                            // Read the data out of the pipe to clear it.
                            Debug.Assert(!isTimeout, "should not have timed out if isExtraFileDescriptorActive");
                            VerboseTrace("curl_multi_wait wake-up notification");
                            ReadFromWakeupPipeWhenKnownToContainData();
                        }
                        VerboseTraceIf(isTimeout, "curl_multi_wait timeout");

                        // PERF NOTE: curl_multi_wait uses poll (assuming it's available), which is O(N) in terms of the number of fds 
                        // being waited on. If this ends up being a scalability bottleneck, we can look into using the curl_multi_socket_* 
                        // APIs, which would let us switch to using epoll by being notified when sockets file descriptors are added or 
                        // removed and configuring the epoll context with EPOLL_CTL_ADD/DEL, which at the expense of a lot of additional
                        // complexity would let us turn the O(N) operation into an O(1) operation.  The additional complexity would come
                        // not only in the form of additional callbacks and managing the socket collection, but also in the form of timer
                        // management, which is necessary when using the curl_multi_socket_* APIs and which we avoid by using just
                        // curl_multi_wait/perform.
                    }
                }
                finally
                {
                    // If we got an unexpected exception, something very bad happened. We may have some 
                    // operations that we initiated but that weren't completed. Make sure to clean up any 
                    // such operations, failing them and releasing their resources.
                    if (_activeOperations.Count > 0)
                    {
                        Debug.Assert(!endingSuccessfully, "We should only have remaining operations if we got an unexpected exception");
                        foreach (KeyValuePair<IntPtr, ActiveRequest> pair in _activeOperations)
                        {
                            ActiveRequest failingOperation = pair.Value;
                            IntPtr failingOperationGcHandle = pair.Key;

                            DeactivateActiveRequest(multiHandle, failingOperation.Easy, failingOperationGcHandle, failingOperation.CancellationRegistration);

                            // Complete the operation's task and clean up any of its resources
                            failingOperation.Easy.FailRequest(CreateHttpRequestException());
                            failingOperation.Easy.Cleanup(); // no active processing remains, so cleanup
                        }

                        // Clear the table.
                        _activeOperations.Clear();
                    }

                    // Finally, dispose of the multi handle.
                    multiHandle.Dispose();
                }
            }
示例#13
0
 public void Active([FromBody] ActiveRequest activeRequest)
 {
     repoOnSite.Active(activeRequest.ActiveThruDateTime, activeRequest.centerId);
 }
示例#14
0
 /// <summary>
 /// 查询部门
 /// </summary>
 /// <param name="listJson">传递的json数据</param>
 /// <param name="dictParam">url上的除access_token参数</param>
 /// <returns></returns>
 public string List(string listJson, Dictionary <string, string> dictParam)
 {
     return(ActiveRequest.SendRequest(this.GetEntityByAction(this._strDepartmentUrl + DepartmentAction.list.ToString(), listJson, dictParam, "get")));
 }
示例#15
0
 /// <summary>
 /// 删除部门
 /// </summary>
 /// <param name="deleteJson">传递的json数据</param>
 /// <param name="dictParam">url上的除access_token参数</param>
 /// <returns></returns>
 public string Delete(string deleteJson, Dictionary <string, string> dictParam)
 {
     return(ActiveRequest.SendRequest(this.GetEntityByAction(this._strDepartmentUrl + DepartmentAction.delete.ToString(), deleteJson, dictParam, "get")));
 }
        public JsonResult SendRequest(string accessToken, string startingAddressMainText, string startingAddressSecondaryText, string startingAddressLocationLat, string startingAddressLocationLng, string finishAddressMainText, string finishAddressSecondaryText, string finishAddressLocationLat, string finishAddressLocationLng)
        {
            if (HttpContext.Request.RequestType == "POST")
            {
                var newAccessToken = _accessTokenService.GenerateAccessToken(accessToken);
                if (newAccessToken == null)
                {
                    return(Json(new { status = "INVALID ACCESSTOKEN" }));
                }

                var userId = _accessTokenService.GetUserId(newAccessToken);
                if (userId == null)
                {
                    return(Json(new { status = "ERR1", accessToken = newAccessToken }));
                }
                var client = _clientService.GetAll().Where(x => x.UserId == userId).FirstOrDefault();
                if (client == null)
                {
                    return(Json(new { status = "ERR2", accessToken = newAccessToken }));
                }
                var anotherRequest = _requestService.GetClientRequest().Where(c => c.Client.Id == client.Id).FirstOrDefault();
                if (anotherRequest != null)
                {
                    return(Json(new { status = "ERR3", accessToken = accessToken }));
                }
                var requestInfo = new RequestInfo()
                {
                    CreatedBy                = CreatedBy.Client,
                    CreatedDateTime          = DateTime.Now,
                    CreatorUserId            = userId,
                    LastModificationDateTime = DateTime.Now,
                    RequestStatus            = RequestStatusEnum.NoCarChosen,
                    StartingAddress          = startingAddressMainText + " " + startingAddressSecondaryText,
                    FinishAddress            = finishAddressMainText + " " + finishAddressSecondaryText,
                    StartingLocation         = new Models.Models.Location()
                    {
                        Latitude  = double.Parse(startingAddressLocationLat),
                        Longitude = double.Parse(startingAddressLocationLng)
                    },
                    FinishLocation = new Models.Models.Location()
                    {
                        Latitude  = double.Parse(finishAddressLocationLat),
                        Longitude = double.Parse(finishAddressLocationLng)
                    }
                };
                _requestService.AddRequestInfo(requestInfo);
                var activeRequest = new ActiveRequest();
                activeRequest.Request           = requestInfo;
                activeRequest.DateTimeChosenCar = DateTime.Now;
                var appropriateCar = _carService.AppropriateCar(new Models.Models.Location()
                {
                    Latitude = double.Parse(startingAddressLocationLat), Longitude = double.Parse(startingAddressLocationLng)
                });
                if (appropriateCar != null)
                {
                    activeRequest.AppropriateCar = appropriateCar;
                    requestInfo.RequestStatus    = RequestStatusEnum.NotTaken;
                    _requestService.ModifyRequestInfo(requestInfo);
                }
                _requestService.AddActiveRequest(activeRequest);

                var clientRequest = new ClientRequest()
                {
                    Client  = client,
                    Request = requestInfo
                };
                _requestService.AddClientRequest(clientRequest);

                return(Json(new { accessToken = newAccessToken, status = "OK" }));
            }
            return(Json(new { }));
        }
示例#17
0
        /// <summary>
        /// 批量删除成员
        /// </summary>
        /// <param name="batchDeleteJson">json字符串</param>
        /// <param name="dictParam">url上的除access_token参数</param>
        /// <returns></returns>
        public string BatchDelete(string batchDeleteJson)
        {
            string strUrl = this._strDepartmentUrl + "user/" + UserAction.batchdelete.ToString();

            return(ActiveRequest.SendRequest(this.GetEntityByAction(strUrl, batchDeleteJson)));
        }
示例#18
0
        /// <summary>
        /// 更新成员
        /// </summary>
        /// <param name="updateJson">json字符串</param>
        /// <returns></returns>
        public string Update(string updateJson)
        {
            string strUrl = this._strDepartmentUrl + "user/" + UserAction.update.ToString();

            return(ActiveRequest.SendRequest(this.GetEntityByAction(strUrl, updateJson)));
        }
示例#19
0
        private void _initializeComponents()
        {
            // Parent Vbox
            VBox ParentContent = new VBox();

            // Request URL in frame
            Frame RequestUrl = new Frame()
            {
                Label   = Director.Properties.Resources.RequestInfoBox,
                Padding = 10
            };
            VBox RequestUrlContent = new VBox();

            RequestUrlContent.PackStart(new Label(Director.Properties.Resources.RequestUrl));
            TextEntry RequestUrlField = new TextEntry()
            {
                Text = ActiveRequest.Url
            };

            RequestUrlContent.PackStart(RequestUrlField, expand: true, fill: true);
            RequestUrlContent.PackStart(InvalidRequestUrl, vpos: WidgetPlacement.End);

            // Method
            RequestUrlContent.PackStart(new Label(Director.Properties.Resources.RequestMethod));
            RequestHttpMethod = new ComboBox();
            RequestHttpMethod.Items.Add(1, "GET");
            RequestHttpMethod.Items.Add(2, "HEAD");
            RequestHttpMethod.Items.Add(3, "POST");
            RequestHttpMethod.Items.Add(4, "PUT");
            RequestHttpMethod.Items.Add(5, "PATCH");
            RequestHttpMethod.Items.Add(6, "DELETE");
            RequestHttpMethod.Items.Add(7, "OPTIONS");
            try
            {
                RequestHttpMethod.SelectedText = ActiveRequest.HTTP_METHOD;
            }
            catch
            {
                RequestHttpMethod.SelectedText = ActiveRequest.HTTP_METHOD = "GET";
            }
            RequestUrlContent.PackStart(RequestHttpMethod);
            RequestHttpMethod.SelectionChanged += delegate
            {
                ActiveRequest.HTTP_METHOD = RequestHttpMethod.SelectedText;
                if (RequestSettings.CurrentTab.Child is OverviewWidget)
                {
                    ((OverviewWidget)RequestSettings.CurrentTab.Child).RefreshOverview();
                }
            };

            // Wait in seconds
            RequestUrlContent.PackStart(new Label(Director.Properties.Resources.WaitPreviousRequest));
            TextEntry WaitTime = new TextEntry()
            {
                Text = ActiveRequest.WaitAfterPreviousRequest + ""
            };

            RequestUrlContent.PackStart(WaitTime, expand: true, fill: true);
            RequestUrlContent.PackStart(InvalidTime, vpos: WidgetPlacement.End);
            WaitTime.Changed += delegate
            {
                try
                {
                    ActiveRequest.WaitAfterPreviousRequest = int.Parse(WaitTime.Text);

                    if (ActiveRequest.WaitAfterPreviousRequest < 0)
                    {
                        ActiveRequest.WaitAfterPreviousRequest = 0;
                        WaitTime.Text = "0";
                        throw new InvalidCastException();
                    }

                    InvalidTime.Visible = false;
                }
                catch
                {
                    InvalidTime.Visible = true;
                }
            };

            // Repeat count
            RequestUrlContent.PackStart(new Label(Director.Properties.Resources.NumberOfCallRepeats));
            TextEntry RepeatCounter = new TextEntry()
            {
                Text = ActiveRequest.RepeatsCounter + ""
            };

            RequestUrlContent.PackStart(RepeatCounter, expand: true, fill: true);
            RequestUrlContent.PackStart(InvalidRepeatCount, vpos: WidgetPlacement.End);
            RepeatCounter.Changed += delegate
            {
                try
                {
                    ActiveRequest.RepeatsCounter = int.Parse(RepeatCounter.Text);

                    if (ActiveRequest.RepeatsCounter < 0)
                    {
                        ActiveRequest.RepeatsCounter = 0;
                        RepeatCounter.Text           = "0";
                        throw new InvalidCastException();
                    }

                    InvalidRepeatCount.Visible = false;
                }
                catch
                {
                    InvalidRepeatCount.Visible = true;
                }
            };

            // Time between repeaters
            RequestUrlContent.PackStart(new Label(Director.Properties.Resources.TimeBetweenRequests));
            TextEntry RequestTimeouts = new TextEntry()
            {
                Text = ActiveRequest.RepeatsTimeout + ""
            };

            RequestUrlContent.PackStart(RequestTimeouts, expand: true, fill: true);
            RequestUrlContent.PackStart(InvalidBetweenRepeatTime, vpos: WidgetPlacement.End);
            RequestTimeouts.Changed += delegate
            {
                try
                {
                    ActiveRequest.RepeatsTimeout = int.Parse(RequestTimeouts.Text);

                    if (ActiveRequest.RepeatsTimeout < 0)
                    {
                        ActiveRequest.RepeatsTimeout = 0;
                        RequestTimeouts.Text         = "0";
                        throw new InvalidCastException();
                    }

                    InvalidBetweenRepeatTime.Visible = false;
                }
                catch
                {
                    InvalidBetweenRepeatTime.Visible = true;
                }
            };

            // Set content
            RequestUrl.Content = RequestUrlContent;
            ParentContent.PackStart(RequestUrl, expand: false, fill: true);

            // Change request URL field
            RequestUrlField.Changed += delegate
            {
                try
                {
                    ActiveRequest.SetUrl(RequestUrlField.Text);
                    InvalidRequestUrl.Hide();
                }
                catch
                {
                    InvalidRequestUrl.Show();
                }
                if (RequestSettings.CurrentTab.Child is OverviewWidget)
                {
                    ((OverviewWidget)RequestSettings.CurrentTab.Child).RefreshOverview();
                }
            };

            // Create Notebook
            RequestSettings = new Notebook()
            {
                ExpandHorizontal = true,
                ExpandVertical   = true,
                TabOrientation   = NotebookTabOrientation.Top
            };
            _initializeTabs();
            RequestSettings.CurrentTabChanged += delegate
            {
                if (RequestSettings.CurrentTab.Child is OverviewWidget)
                {
                    ((OverviewWidget)RequestSettings.CurrentTab.Child).RefreshOverview();
                }
            };
            ParentContent.PackStart(RequestSettings, true, true);

            // Close btn
            Button ConfirmButton = new Button(Image.FromResource(DirectorImages.OK_ICON),
                                              Director.Properties.Resources.Confirm)
            {
                WidthRequest     = 150,
                ExpandHorizontal = false,
                ExpandVertical   = false
            };

            ConfirmButton.Clicked += delegate { Close(); };
            ParentContent.PackStart(ConfirmButton, expand: false, hpos: WidgetPlacement.End);

            // Set content
            Content = ParentContent;
        }
示例#20
0
            private void WorkerLoop()
            {
                Debug.Assert(!Monitor.IsEntered(_incomingRequests), "No locks should be held while invoking Process");
                Debug.Assert(_runningWorker != null && _runningWorker.Id == Task.CurrentId, "This is the worker, so it must be running");
                Debug.Assert(_wakeupRequestedPipeFd != 0, "Should have a valid pipe for wake ups");

                // Create the multi handle to use for this round of processing.  This one handle will be used
                // to service all easy requests currently available and all those that come in while
                // we're processing other requests.  Once the work quiesces and there are no more requests
                // to process, this multi handle will be released as the worker goes away.  The next
                // time a request arrives and a new worker is spun up, a new multi handle will be created.
                SafeCurlMultiHandle multiHandle = Interop.libcurl.curl_multi_init();

                if (multiHandle.IsInvalid)
                {
                    throw CreateHttpRequestException();
                }

                // Clear our active operations table.  This should already be clear, either because
                // all previous operations completed without unexpected exception, or in the case of an
                // unexpected exception we should have cleaned up gracefully anyway.  But just in case...
                Debug.Assert(_activeOperations.Count == 0, "We shouldn't have any active operations when starting processing.");
                _activeOperations.Clear();

                bool endingSuccessfully = false;

                try
                {
                    // Continue processing as long as there are any active operations
                    while (true)
                    {
                        // First handle any requests in the incoming requests queue.
                        while (true)
                        {
                            IncomingRequest request;
                            lock (_incomingRequests)
                            {
                                if (_incomingRequests.Count == 0)
                                {
                                    break;
                                }
                                request = _incomingRequests.Dequeue();
                            }
                            HandleIncomingRequest(multiHandle, request);
                        }

                        // If we have no active operations, we're done.
                        if (_activeOperations.Count == 0)
                        {
                            endingSuccessfully = true;
                            return;
                        }

                        // We have one or more active operations. Run any work that needs to be run.
                        int running_handles;
                        ThrowIfCURLMError(Interop.libcurl.curl_multi_perform(multiHandle, out running_handles));

                        // Complete and remove any requests that have finished being processed.
                        int    pendingMessages;
                        IntPtr messagePtr;
                        while ((messagePtr = Interop.libcurl.curl_multi_info_read(multiHandle, out pendingMessages)) != IntPtr.Zero)
                        {
                            Interop.libcurl.CURLMsg message = Marshal.PtrToStructure <Interop.libcurl.CURLMsg>(messagePtr);
                            Debug.Assert(message.msg == Interop.libcurl.CURLMSG.CURLMSG_DONE, "CURLMSG_DONE is supposed to be the only message type");

                            IntPtr        gcHandlePtr;
                            ActiveRequest completedOperation;
                            if (message.msg == Interop.libcurl.CURLMSG.CURLMSG_DONE)
                            {
                                int getInfoResult = Interop.libcurl.curl_easy_getinfo(message.easy_handle, CURLINFO.CURLINFO_PRIVATE, out gcHandlePtr);
                                Debug.Assert(getInfoResult == CURLcode.CURLE_OK, "Failed to get info on a completing easy handle");
                                if (getInfoResult == CURLcode.CURLE_OK)
                                {
                                    bool gotActiveOp = _activeOperations.TryGetValue(gcHandlePtr, out completedOperation);
                                    Debug.Assert(gotActiveOp, "Expected to find GCHandle ptr in active operations table");
                                    if (gotActiveOp)
                                    {
                                        DeactivateActiveRequest(multiHandle, completedOperation.Easy, gcHandlePtr, completedOperation.CancellationRegistration);
                                        FinishRequest(completedOperation.Easy, message.result);
                                    }
                                }
                            }
                        }

                        // Wait for more things to do.  Even with our cancellation mechanism, we specify a timeout so that
                        // just in case something goes wrong we can recover gracefully.  This timeout is relatively long.
                        // Note, though, that libcurl has its own internal timeout, which can be requested separately
                        // via curl_multi_timeout, but which is used implicitly by curl_multi_wait if it's shorter
                        // than the value we provide.
                        const int FailsafeTimeoutMilliseconds = 1000;
                        int       numFds;
                        unsafe
                        {
                            Interop.libcurl.curl_waitfd extraFds = new Interop.libcurl.curl_waitfd {
                                fd      = _wakeupRequestedPipeFd,
                                events  = Interop.libcurl.CURL_WAIT_POLLIN,
                                revents = 0
                            };
                            ThrowIfCURLMError(Interop.libcurl.curl_multi_wait(multiHandle, &extraFds, 1, FailsafeTimeoutMilliseconds, out numFds));
                            if ((extraFds.revents & Interop.libcurl.CURL_WAIT_POLLIN) != 0)
                            {
                                // We woke up (at least in part) because a wake-up was requested.
                                // Read the data out of the pipe to clear it.
                                Debug.Assert(numFds >= 1, "numFds should have been at least one, as the extraFd was set");
                                VerboseTrace("curl_multi_wait wake-up notification");
                                ReadFromWakeupPipeWhenKnownToContainData();
                            }
                            VerboseTraceIf(numFds == 0, "curl_multi_wait timeout");
                        }

                        // PERF NOTE: curl_multi_wait uses poll (assuming it's available), which is O(N) in terms of the number of fds
                        // being waited on. If this ends up being a scalability bottleneck, we can look into using the curl_multi_socket_*
                        // APIs, which would let us switch to using epoll by being notified when sockets file descriptors are added or
                        // removed and configuring the epoll context with EPOLL_CTL_ADD/DEL, which at the expense of a lot of additional
                        // complexity would let us turn the O(N) operation into an O(1) operation.  The additional complexity would come
                        // not only in the form of additional callbacks and managing the socket collection, but also in the form of timer
                        // management, which is necessary when using the curl_multi_socket_* APIs and which we avoid by using just
                        // curl_multi_wait/perform.
                    }
                }
                finally
                {
                    // If we got an unexpected exception, something very bad happened. We may have some
                    // operations that we initiated but that weren't completed. Make sure to clean up any
                    // such operations, failing them and releasing their resources.
                    if (_activeOperations.Count > 0)
                    {
                        Debug.Assert(!endingSuccessfully, "We should only have remaining operations if we got an unexpected exception");
                        foreach (KeyValuePair <IntPtr, ActiveRequest> pair in _activeOperations)
                        {
                            ActiveRequest failingOperation         = pair.Value;
                            IntPtr        failingOperationGcHandle = pair.Key;

                            DeactivateActiveRequest(multiHandle, failingOperation.Easy, failingOperationGcHandle, failingOperation.CancellationRegistration);

                            // Complete the operation's task and clean up any of its resources
                            failingOperation.Easy.FailRequest(CreateHttpRequestException());
                            failingOperation.Easy.Cleanup(); // no active processing remains, so cleanup
                        }

                        // Clear the table.
                        _activeOperations.Clear();
                    }

                    // Finally, dispose of the multi handle.
                    multiHandle.Dispose();
                }
            }
示例#21
0
 /// <summary>
 /// Add an Active Request
 /// </summary>
 /// <param name="request"></param>
 public void AddActiveRequest(ActiveRequest request)
 {
     data.ActiveRequests.Add(request);
     data.SaveChanges();
 }
示例#22
0
 /// <summary>
 /// Refresh overview summary.
 /// </summary>
 public void RefreshOverview()
 {
     ActiveRequest.CreateOverview(Overview, Font.WithSize(17).WithWeight(FontWeight.Bold));
 }
示例#23
0
            private void Process()
            {
                Debug.Assert(!Monitor.IsEntered(_incomingRequests), "No locks should be held while invoking Process");
                Debug.Assert(_workerRunning, "This is the worker, so it must be running");
                Debug.Assert(_wakeupRequestedPipeFd != 0, "Should have a valid pipe for wake ups");

                // Create the multi handle to use for this round of processing.  This one handle will be used
                // to service all easy requests currently available and all those that come in while
                // we're processing other requests.  Once the work quiesces and there are no more requests
                // to process, this multi handle will be released as the worker goes away.  The next
                // time a request arrives and a new worker is spun up, a new multi handle will be created.
                SafeCurlMultiHandle multiHandle = Interop.libcurl.curl_multi_init();

                if (multiHandle.IsInvalid)
                {
                    throw CreateHttpRequestException();
                }

                // Clear our active operations table.  This should already be clear, either because
                // all previous operations completed without unexpected exception, or in the case of an
                // unexpected exception we should have cleaned up gracefully anyway.  But just in case...
                Debug.Assert(_activeOperations.Count == 0, "We shouldn't have any active operations when starting processing.");
                _activeOperations.Clear();

                bool endingSuccessfully = false;

                try
                {
                    // Continue processing as long as there are any active operations
                    while (true)
                    {
                        // Activate any new operations that were submitted, and cancel any operations
                        // that should no longer be around.
                        lock (_incomingRequests)
                        {
                            while (_incomingRequests.Count > 0)
                            {
                                EasyRequest easy = _incomingRequests.Dequeue();
                                Debug.Assert(easy._associatedMultiAgent == null || easy._associatedMultiAgent == this, "An incoming request must only be associated with no or this agent");
                                if (easy._associatedMultiAgent == null)
                                {
                                    // Handle new request
                                    ActivateNewRequest(multiHandle, easy);
                                }
                                else
                                {
                                    // Handle cancellation request.
                                    Debug.Assert(easy.CancellationToken.IsCancellationRequested, "_associatedMultiAgent should only be non-null if cancellation was requested");
                                    IntPtr        gcHandlePtr;
                                    ActiveRequest activeRequest;
                                    if (FindActiveRequest(easy, out gcHandlePtr, out activeRequest))
                                    {
                                        DeactivateActiveRequest(multiHandle, easy, gcHandlePtr, activeRequest.CancellationRegistration);
                                        easy.FailRequest(new OperationCanceledException(easy.CancellationToken));
                                        easy.Cleanup(); // no active processing remains, so we can cleanup
                                    }
                                    else
                                    {
                                        Debug.Assert(easy.Task.IsCompleted, "We should only not be able to find the request if it was already completed.");
                                    }
                                }
                            }
                        }

                        // If we have no active operations, we're done.
                        if (_activeOperations.Count == 0)
                        {
                            endingSuccessfully = true;
                            return;
                        }

                        // We have one or more active operaitons. Run any work that needs to be run.
                        int running_handles;
                        ThrowIfCURLMError(Interop.libcurl.curl_multi_perform(multiHandle, out running_handles));

                        // Complete and remove any requests that have finished being processed.
                        int    pendingMessages;
                        IntPtr messagePtr;
                        while ((messagePtr = Interop.libcurl.curl_multi_info_read(multiHandle, out pendingMessages)) != IntPtr.Zero)
                        {
                            Interop.libcurl.CURLMsg message = Marshal.PtrToStructure <Interop.libcurl.CURLMsg>(messagePtr);
                            IntPtr        gcHandlePtr;
                            ActiveRequest completedOperation;
                            if (message.msg == Interop.libcurl.CURLMSG.CURLMSG_DONE &&
                                Interop.libcurl.curl_easy_getinfo(message.easy_handle, CURLINFO.CURLINFO_PRIVATE, out gcHandlePtr) == CURLcode.CURLE_OK &&
                                _activeOperations.TryGetValue(gcHandlePtr, out completedOperation))
                            {
                                DeactivateActiveRequest(multiHandle, completedOperation.Easy, gcHandlePtr, completedOperation.CancellationRegistration);
                                FinishRequest(completedOperation.Easy, message.result);
                            }
                        }

                        // Wait for more things to do.  Even with our cancellation mechanism, we specify a timeout so that
                        // just in case something goes wrong we can recover gracefully.  This timeout is relatively long.
                        // Note, though, that libcurl has its own internal timeout, which can be requested separately
                        // via curl_multi_timeout, but which is used implicitly by curl_multi_wait if it's shorter
                        // than the value we provide.
                        const int FailsafeTimeoutMilliseconds = 1000;
                        int       numFds;
                        unsafe
                        {
                            Interop.libcurl.curl_waitfd extraFds = new Interop.libcurl.curl_waitfd {
                                fd      = _wakeupRequestedPipeFd,
                                events  = Interop.libcurl.CURL_WAIT_POLLIN,
                                revents = 0
                            };
                            ThrowIfCURLMError(Interop.libcurl.curl_multi_wait(multiHandle, &extraFds, 1, FailsafeTimeoutMilliseconds, out numFds));
                            if ((extraFds.revents & Interop.libcurl.CURL_WAIT_POLLIN) != 0)
                            {
                                // We woke up (at least in part) because a wake-up was requested.  Read the data out of the pipe
                                // to clear it. It's possible but unlikely that there will be tons of extra data in the pipe,
                                // more than we end up reading out here (it's unlikely because we only write a byte to the pipe when
                                // transitioning from 0 to 1 incoming request or when cancellation is requested, and that would
                                // need to happen many times in a single iteration).  In that unlikely case, we'll simply loop
                                // around again as normal and end up waking up spuriously from the next curl_multi_wait.  For now,
                                // this is preferable to making additional syscalls to poll and read from the pipe).
                                const int ClearBufferSize = 4096; // some sufficiently large size to clear the pipe in any normal case
                                byte *    clearBuf        = stackalloc byte[ClearBufferSize];
                                while (Interop.CheckIo((long)Interop.libc.read(_wakeupRequestedPipeFd, clearBuf, (IntPtr)ClearBufferSize)))
                                {
                                    ;
                                }
                            }
                        }

                        // PERF NOTE: curl_multi_wait uses poll (assuming it's available), which is O(N) in terms of the number of fds
                        // being waited on. If this ends up being a scalability bottleneck, we can look into using the curl_multi_socket_*
                        // APIs, which would let us switch to using epoll by being notified when sockets file descriptors are added or
                        // removed and configuring the epoll context with EPOLL_CTL_ADD/DEL, which at the expense of a lot of additional
                        // complexity would let us turn the O(N) operation into an O(1) operation.  The additional complexity would come
                        // not only in the form of additional callbacks and managing the socket collection, but also in the form of timer
                        // management, which is necessary when using the curl_multi_socket_* APIs and which we avoid by using just
                        // curl_multi_wait/perform.
                    }
                }
                finally
                {
                    // If we got an unexpected exception, something very bad happened. We may have some
                    // operations that we initiated but that weren't completed. Make sure to clean up any
                    // such operations, failing them and releasing their resources.
                    if (_activeOperations.Count > 0)
                    {
                        Debug.Assert(!endingSuccessfully, "We should only have remaining operations if we got an unexpected exception");
                        foreach (KeyValuePair <IntPtr, ActiveRequest> pair in _activeOperations)
                        {
                            ActiveRequest failingOperation         = pair.Value;
                            IntPtr        failingOperationGcHandle = pair.Key;

                            DeactivateActiveRequest(multiHandle, failingOperation.Easy, failingOperationGcHandle, failingOperation.CancellationRegistration);

                            // Complete the operation's task and clean up any of its resources
                            failingOperation.Easy.FailRequest(CreateHttpRequestException());
                            failingOperation.Easy.Cleanup(); // no active processing remains, so cleanup
                        }

                        // Clear the table.
                        _activeOperations.Clear();
                    }

                    // Finally, dispose of the multi handle.
                    multiHandle.Dispose();
                }
            }
示例#24
0
        /// <summary>
        /// 邀请成员关注
        /// </summary>
        /// <param name="sendJson">json字符串</param>
        /// <param name="dictParam">url上的除access_token参数</param>
        /// <returns></returns>
        public string Send(string sendJson)
        {
            string strUrl = this._strDepartmentUrl + "invite/" + UserAction.send.ToString();

            return(ActiveRequest.SendRequest(this.GetEntityByAction(strUrl, sendJson)));
        }
示例#25
0
 /// <summary>
 /// 创建菜单
 /// </summary>
 /// <param name="strJson">传递的json数据</param>
 /// <param name="dictParam">url上的除access_token参数</param>
 /// <returns>返回json结果</returns>
 public string Create(string strJson, Dictionary <string, string> dictParam)
 {
     return(ActiveRequest.SendRequest(this.GetEntityByAction(this._strMenuUrl + MenuAction.create.ToString(), strJson, dictParam)));
 }
示例#26
0
        /// <summary>
        /// 删除成员
        /// </summary>
        /// <param name="deleteJson">json字符串</param>
        /// <param name="dictParam">url上的除access_token参数</param>
        /// <returns></returns>
        public string Delete(string deleteJson, Dictionary <string, string> dictParam)
        {
            string strUrl = this._strDepartmentUrl + "user/" + UserAction.delete.ToString();

            return(ActiveRequest.SendRequest(this.GetEntityByAction(strUrl, deleteJson, dictParam, "get")));
        }
示例#27
0
        /// <summary>
        /// 获取菜单列表(全部菜单)
        /// </summary>
        /// <param name="dictParam">url上的除access_token参数</param>
        /// <returns></returns>
        public string Get(Dictionary <string, string> dictParam)
        {
            string strUrl = this._strMenuUrl + MenuAction.get.ToString();

            return(ActiveRequest.SendRequest(this.GetEntityByAction(strUrl, "", dictParam, "get")));
        }
示例#28
0
        /// <summary>
        /// 获取部门成员
        /// </summary>
        /// <param name="simpleListJson">json字符串</param>
        /// <param name="dictParam">url上的除access_token参数</param>
        /// <returns></returns>
        public string SimpleList(string simpleListJson, Dictionary <string, string> dictParam)
        {
            string strUrl = this._strDepartmentUrl + "user/" + UserAction.simplelist.ToString();

            return(ActiveRequest.SendRequest(this.GetEntityByAction(strUrl, simpleListJson, dictParam, "get")));
        }
示例#29
0
 /// <summary>
 /// 创建部门
 /// </summary>
 /// <param name="createJson">json字符串</param>
 /// <param name="dictParam">url上的除access_token参数</param>
 /// <returns></returns>
 public string Create(string createJson, Dictionary <string, string> dictParam)
 {
     return(ActiveRequest.SendRequest(this.GetEntityByAction(this._strDepartmentUrl + DepartmentAction.create.ToString(), createJson, dictParam)));
 }
示例#30
0
 private bool FindActiveRequest(EasyRequest easy, out IntPtr gcHandlePtr, out ActiveRequest activeRequest)
 {
     // We maintain an IntPtr=>ActiveRequest mapping, which makes it cheap to look-up by GCHandle ptr but
     // expensive to look up by EasyRequest.  If we find this becoming a bottleneck, we can add a reverse
     // map that stores the other direction as well.
     foreach (KeyValuePair<IntPtr, ActiveRequest> pair in _activeOperations)
     {
         if (pair.Value.Easy == easy)
         {
             gcHandlePtr = pair.Key;
             activeRequest = pair.Value;
             return true;
         }
     }
     gcHandlePtr = IntPtr.Zero;
     activeRequest = default(ActiveRequest);
     return false;
 }
示例#31
0
 /// <summary>
 /// 更新部门
 /// </summary>
 /// <param name="UpdateJson">json字符串</param>
 /// <returns></returns>
 public string Update(string UpdateJson)
 {
     return(ActiveRequest.SendRequest(this.GetEntityByAction(this._strDepartmentUrl + DepartmentAction.update.ToString(), UpdateJson)));
 }