protected override bool ProcessResponse(string text) { if (!base.ProcessResponse(text)) { return(false); } int numberOfCommandsSent = NumberOfCommandsToSend; Facade.IncrementProgressBar(NumberOfCommandsToSend); //3: Send the rest of sync commands if (Facade.MoreSyncCommands) { SendingSyncMessage sendingSyncStep = new SendingSyncMessage(Facade); sendingSyncStep.Send(); if (!Facade.SoFarOK) { Trace.TraceInformation("Somethng wrong in message returned from the server."); return(false); } numberOfCommandsSent += sendingSyncStep.NumberOfCommandsToSend; if (Facade.GracefulStop) { return(false); } } else { Facade.DisplayStageMessage("Sending Done"); CleanUp(); } return(true); }
///// <summary> ///// Send dummy message to server to avoid timeout. Funambol/Apache seems to have timeout of 15 minutes by default, ///// though I could not alter it through C:\Program Files\Funambol\ds-server\default\config\tomcat\xml\WEB-INF\web.xml ///// 100 minutes should be long enough. ///// </summary> //void KeepServerBusy() //{ // for (int i = 0; i < 360; i++)// so 6 hours // { // if (CommandsSourceGenerated) // break; // System.Threading.Thread.Sleep(60000);//so ping every 1 minute // if (CommandsSourceGenerated) // break; // string s = Facade.Connections.GetResponseText("Silly Ping"); // Debug.WriteLine("Server response to ping: " + s); // } // Debug.WriteLine("KeepServerBusy end"); //} // static object myLock = new object(); //bool commandsSourceGenerated; //bool CommandsSourceGenerated //{ // get // { // lock (myLock) // { // return commandsSourceGenerated; // } // } // set // { // lock (myLock) // { // commandsSourceGenerated = value; // } // } //} /// <summary> /// Send sync content in one or more messages. /// This function will spin out two thread, one for preparing commands source, /// and the other to keey server busy to avoid timeout, as the localDataSource /// might need long time to prepare data. /// </summary> /// <param name="slowSync">True to do slow sync.</param> private void SendSyncContent(bool slowSync) { //1: Generate SyncCommands in a buffer try { DateTime anchor = slowSync ? DateTime.MinValue : Facade.LastAnchorTime; // CommandsSourceGenerated = false; Action <DateTime> prepare = PrepareCommandsSource; IAsyncResult resultOfPrepare = prepare.BeginInvoke(anchor, null, null); // Action sillyPing = KeepServerBusy; // IAsyncResult resultOfSillyPing = sillyPing.BeginInvoke(null, null); try { System.Threading.WaitHandle.WaitAny( new System.Threading.WaitHandle[] { resultOfPrepare.AsyncWaitHandle }); //, resultOfSillyPing.AsyncWaitHandle Debug.WriteLine("WaitAny end"); //generally the preparation finishs first. prepare.EndInvoke(resultOfPrepare); Debug.WriteLine("Parpare End"); /* if (System.Threading.WaitHandle.SignalAndWait(resultOfSillyPing.AsyncWaitHandle, resultOfPrepare.AsyncWaitHandle)) * { * Debug.WriteLine("Both Preparation and SillyPing end"); * } * else * { * sillyPing.EndInvoke(resultOfSillyPing); * Debug.WriteLine("SillyPing End"); * }*/ // now 2 threads join } catch (Exception e) { Trace.TraceWarning("wrong here: " + e.ToString()); Facade.SoFarOK = false; throw new FacadeErrorException("Preparation or SillyPing might be wrong.", e); } if (Facade.CommandsToSend == null) { Trace.TraceInformation("Can not get CommandsSource from thd local data source."); Facade.SoFarOK = false; return; } } catch (FacadeErrorException e) // triggered by XsltException { Trace.TraceInformation("When SendSyncContent: " + e.Message); if (e.InnerException != null) { Trace.TraceInformation(e.InnerException.ToString() + "~" + e.InnerException.Message); } Facade.SoFarOK = false; return; } Facade.totalNumberOfChangesSending = Facade.CommandsToSend.NumberOfChanges; if (Facade.totalNumberOfChangesSending > 0) { Facade.DisplayOperationMessage(String.Format("Total number of changes to be sent to the server: {0}", Facade.totalNumberOfChangesSending)); Facade.DisplayOperationMessage(Facade.LocalDataSource.SummaryOfGeneratedSyncCommands); Facade.InitProgressBar(0, Facade.totalNumberOfChangesSending, SyncConstants.MaxCommandsPerBatch); Facade.DisplayStageMessage(String.Format("Sending {0} updates ...", Facade.totalNumberOfChangesSending)); } if (Facade.GracefulStop) { return; } //2: Send the first batch of sync commands, then may be recursive call to SendinSyncMessage int numberOfCommandsSent = 0; SendingSyncMessage sendingSyncStep = new SendingSyncMessage(Facade, Facade.totalNumberOfChangesSending); sendingSyncStep.Send(); numberOfCommandsSent += sendingSyncStep.NumberOfCommandsToSend; Facade.IncrementProgressBar(sendingSyncStep.NumberOfCommandsToSend); if (Facade.GracefulStop) { return; } }