示例#1
0
        public override void Initialize(string projectToken, string appVersion, string target)
        {
            this.projectToken = projectToken;
            this.appVersion   = appVersion;

            deviceProperties = Device.GetProperties();
            customerIds      = storage.GetIds();

            commandQueue = new PersistentBulkCommandQueue("events", Constants.BULK_LIMIT);

            sender = new Sender.Sender((target != null) ? target : Constants.DEFAULT_TARGET, commandQueue);
        }
示例#2
0
        /// <summary>
        /// Periodically performs the following steps:
        ///  0. keep alive the session
        //   1. collect the freshest command bulk
        //	 2. try-send bulk
        //   3. validate response
        //   4. parse response and enqueue for retry if needed
        //   5. wait for N seconds (N grows with the number of consecutive connection failures)
        /// </summary>
        /// <returns>The send loop enumerator.</returns>
        private IEnumerator APISendLoop(string target, PersistentBulkCommandQueue commandQueue)
        {
            const int WAIT_FOR_DEFAULT          = 3;
            var       httpTarget                = target + Constants.BULK_URL;
            int       consecutiveFailedRequests = 0;

            while (true)
            {
                // Decide if we process retry commands or new commands in this round
                List <object> commands = commandQueue.BulkDequeue(true);

                if (commands.Count > 0)
                {
                    // 1B: Prepare the http components
                    var httpBody = Json.Serialize(new Dictionary <string, object> {
                        { "commands", commands }
                    });
                    byte[] httpBodyBytes = Encoding.UTF8.GetBytes(httpBody);

                    // 2. Send the bulk API request
                    UnityWebRequest req = new UnityWebRequest(httpTarget, "POST");
                    req.uploadHandler   = (UploadHandler) new UploadHandlerRaw(httpBodyBytes);
                    req.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer();
                    req.SetRequestHeader("Content-Type", "application/json");

                    yield return(req.SendWebRequest());


                    // 3A: Check response for errors
                    if (!string.IsNullOrEmpty(req.error))
                    {
                        consecutiveFailedRequests++;
                    }
                    else
                    {
                        // 3B. Parse the API response
                        var responseBody = req.downloadHandler.text;
                        Dictionary <string, object> apiResponse =
                            (Dictionary <string, object>)Json.Deserialize(responseBody);
                        bool success = (bool)apiResponse["success"];
                        if (success)
                        {
                            consecutiveFailedRequests = 0;

                            // 4A: extract retry-commands and queue them back (if any)
                            var retryCommands = ExtractRetryCommands(apiResponse, commands);
                            commandQueue.MultiDequeue(commands.Count); //remove every command from this request
                            commandQueue.MultiPush(retryCommands);     //re-add failed commands with the highest priority
                        }
                        else
                        {
                            consecutiveFailedRequests++;
                        }
                    }
                }

                // 5. Detemine wait time and go idle.
                float waitSeconds =
                    (float)System.Math.Pow(WAIT_FOR_DEFAULT, System.Math.Sqrt(consecutiveFailedRequests + 1));
                if (consecutiveFailedRequests == 0 && commandQueue.ElementCount > 0)
                {
                    waitSeconds = 0f;
                }
                waitSeconds = System.Math.Min(waitSeconds, Constants.BULK_MAX - 3f);

                yield return(new WaitForSeconds(waitSeconds));
            }
        }
示例#3
0
 public Sender(string target, PersistentBulkCommandQueue commandQueue)
 {
     this.StartCoroutine(APISendLoop(target, commandQueue));
     _target = target;
 }