public HttpResponseMessage BeginSession(JObject request) { var resp = Request.CreateResponse(HttpStatusCode.OK, string.Empty); ValidateRequest(request, false); if (_userService.GetSessionId((string)request["username"]) != null) { ThrowSafeException("Session In Progress", 1, HttpStatusCode.ServiceUnavailable); } string sessionId = Guid.NewGuid().ToString(); _syncSessionDbConnectionProvider.SessionStart(sessionId); using (ISyncableStore store = _userService.GetSyncableStore(_username)) using (IDbConnection connection = _syncSessionDbConnectionProvider.GetSyncSessionDbConnection(sessionId)) { var json = new SyncServerSession(store, connection).BeginSession(request); json.Add(new JProperty("sessionID", sessionId)); _userService.SetSessionId(_username, sessionId); resp.Content = new StringContent(json.ToString(), Encoding.UTF8, "application/json"); } return(resp); }
public SyncSession(ISyncableStore store, ISyncSessionDbConnectionProvider syncSessionDbConnectionProvider, ISyncTransport transport) { if (store == null) { throw new ArgumentNullException("store"); } if (syncSessionDbConnectionProvider == null) { throw new ArgumentNullException("syncSessionDbConnectionProvider"); } if (transport == null) { throw new ArgumentNullException("transport"); } PushMaxBatchCount = 500; PushMaxBatchSize = 1024 * 1024; PullMaxBatchCount = 5000; PullMaxBatchSize = 1024 * 1024 * 10; _store = store; _syncSessionDbConnectionProvider = syncSessionDbConnectionProvider; _transport = transport; _localSessionId = Guid.NewGuid().ToString(); _syncSessionDbConnectionProvider.SessionStart(_localSessionId); using (var connection = _syncSessionDbConnectionProvider.GetSyncSessionDbConnection(_localSessionId)) { SessionDbHelper.CreateSessionDbTables(connection); } }
private async Task <IEnumerable <SyncConflict> > PullChanges() { ReportProgressAndCheckCacellation(new SyncProgress { Stage = SyncStage.FindingRemoteChanges, PercentComplete = 0, Message = "Looking for remote changes" }); var request = new JObject { { "sessionID", _remoteSessionId } }; var localKnowledge = _store.GenerateLocalKnowledge().ToList(); request.Add(new JProperty("knowledge", SyncUtil.KnowledgeToJson(localKnowledge))); JObject response = await _transport.TransportAsync(SyncEndpoint.GetChanges, request); _remoteKnowledge = SyncUtil.KnowledgeFromJson(response["knowledge"]); var totalChanges = (int)response["totalChanges"]; ReportProgressAndCheckCacellation(new SyncProgress { Stage = SyncStage.FindingRemoteChanges, PercentComplete = 100, Message = String.Format("Found {0} remote changes", totalChanges) }); ReportProgressAndCheckCacellation(new SyncProgress { Stage = SyncStage.DownloadingRemoteChanges, PercentComplete = 0, Message = String.Format("Downloading {0} remote changes", totalChanges) }); using (var connection = _syncSessionDbConnectionProvider.GetSyncSessionDbConnection(_localSessionId)) { connection.ExecuteNonQuery("BEGIN"); SessionDbHelper.ClearSyncItems(connection); long startTick = Environment.TickCount; int previousPercentComplete = -1; for (int i = 1; i <= totalChanges;) { i += await SaveChangesBatch(connection, localKnowledge, i); int percentComplete = ((i * 100) / totalChanges); if (percentComplete != previousPercentComplete) { ReportProgressAndCheckCacellation(new SyncProgress { Stage = SyncStage.DownloadingRemoteChanges, PercentComplete = percentComplete, Message = String.Format("Downloading remote changes, {0}% complete ({1})", percentComplete, String.Format("Averaging {0}ms/item over {1} items", (Environment.TickCount - startTick) / i, i)) }); } previousPercentComplete = percentComplete; } connection.ExecuteNonQuery("COMMIT"); ReportProgressAndCheckCacellation(new SyncProgress { Stage = SyncStage.DownloadingRemoteChanges, PercentComplete = 100, Message = String.Format("Downloaded all {0} remote changes", totalChanges) }); ReportProgressAndCheckCacellation(new SyncProgress { Stage = SyncStage.CheckingForConflicts, PercentComplete = 0, Message = "Looking for conflicts" }); var conflicts = new List <SyncConflict>(); conflicts.AddRange(CheckForDuplicates(connection)); conflicts.AddRange(LoadConflicts(connection)); ReportProgressAndCheckCacellation(new SyncProgress { Stage = SyncStage.CheckingForConflicts, PercentComplete = 100, Message = String.Format("Found {0} conflicts", conflicts.Count) }); return(conflicts); } }