public RavenRemoteQueueTransporter(RavenFactory ravenFactory, string endpointName, string processIdentity) { _ravenFactory = ravenFactory; _endpointName = endpointName; _processIdentity = processIdentity; _tokenSource = new CancellationTokenSource(); }
void Work(RavenTransportMessage message) { var transportMessage = new TransportMessage(message.Id, message.Headers); transportMessage.Body = message.Body; transportMessage.MessageIntent = message.MessageIntent; using (var session = RavenFactory.StartSession(transportMessage.Id)) { Exception exception = null; try { _tryProcessMessage(transportMessage); } catch (Exception e) { exception = e; } finally { RavenFactory.EndSession(transportMessage.Id); } _endProcessMessage(transportMessage, exception); session.Store(message); //attach message to session session.Delete(message); //message.Destination = "trash"; session.SaveChanges(); //session.Advanced.DocumentStore.DatabaseCommands.ForDatabase((session as DocumentSession).DatabaseName).Delete(message.Id, null); } }
public void Send(TransportMessage message, SendOptions sendOptions) { var counter = DateTime.UtcNow.Ticks; var ravenTransportMessage = new RavenTransportMessage(message, sendOptions, counter); //push all outbound messages to the endpoint db RavenFactory.UsingSession(message.CorrelationId, session => session.Store(ravenTransportMessage)); }
void Lead() { using (var session = RavenFactory.OpenSession()) { session.Advanced.UseOptimisticConcurrency = true; var l = session.Advanced.Lazily.Load <Leadership>(Leadership.Identifier); var f = session.Advanced.Lazily.LoadStartingWith <Followership>(Followership.IdPrefix); session.Advanced.Eagerly.ExecuteAllPendingLazyOperations(); var leadership = l.Value; var followers = f.Value.ToList(); var me = followers.FirstOrDefault(x => x.FollowerId == ProcessIdentity); if (me == null) { return; } if (me.ConsideringCoup) { if (leadership == null) { leadership = new Leadership(); session.Store(leadership); } if (leadership.IsHumbleFollower(ProcessIdentity)) { leadership.UsurpPower(ProcessIdentity); session.SaveChanges(); //throw if someone else beats me //TODO: Log Won Election! } } if (leadership == null) { return; } if (leadership.IsHumbleFollower(ProcessIdentity)) { return; } leadership.CommandFollowers(followers); var dead = followers.Where(leadership.IsDeadFollower).ToList(); dead.ForEach(session.Delete); session.SaveChanges(); Console.WriteLine("counts... {0}, {1}", _workQueue.Count, InProgress.Count); } }
public void CreateQueueIfNecessary(Address address, string account) { if (address.Queue.StartsWith(EndpointName) && address.Queue != EndpointName) { return; //combine all queues for an endpoint in one db } var store = RavenFactory .FindDocumentStore(address.Queue); store .DatabaseCommands.GlobalAdmin .EnsureDatabaseExists(address.Queue); var commands = store.DatabaseCommands.ForDatabase(address.Queue); new RavenTransportMessageIndex().Execute(commands, store.Conventions); //todo: log that we are creating db }
void Follow() { using (var session = RavenFactory.OpenSession()) { var l = session.Advanced.Lazily.Load <Leadership>(Leadership.Identifier); var m = session.Advanced.Lazily.Load <Followership>(Followership.FormatId(ProcessIdentity)); session.Advanced.Eagerly.ExecuteAllPendingLazyOperations(); var leadership = l.Value ?? new Leadership(); var me = m.Value; if (me == null) { me = new Followership(ProcessIdentity); session.Store(me); } if (leadership.Status == Leadership.ClusterStatus.Turmoil || leadership.DeniedAssignment(ProcessIdentity)) { while (_workQueue.Count > 0) { RavenTransportMessage trash; _workQueue.TryTake(out trash); //clear the queue } Thread.Sleep(10); //make sure workers have enough time to get their work in the InProgress collection RecentMessages.Clear(); //we're clearing the decks, so forget what we've seen and rely on db } if (RecentMessages.Count == 0) { me.LastSequenceNumber = 0; } if (leadership.Status == Leadership.ClusterStatus.Harmony && leadership.HasAssignment(ProcessIdentity)) { var assignment = leadership.GetAssignment(ProcessIdentity); var take = MaxMessagesToRead - _workQueue.Count; RavenQueryStatistics stats = null; var messages = session.Query <RavenTransportMessage, RavenTransportMessageIndex>() .Statistics(out stats) .Where(x => x.Destination == _address.Queue) .Where(x => x.ClaimTicket >= assignment.LowerBound && x.ClaimTicket <= assignment.UpperBound) .Where(x => x.SequenceNumber >= me.LastSequenceNumber) .OrderBy(x => x.SequenceNumber) .Take(take) .ToList(); Console.WriteLine("Follower Query Stats: {0:N0}", stats.DurationMilliseconds); messages = messages.Where(x => !RecentMessages.Contains(x.Id)).ToList(); messages.ForEach(_workQueue.Add); messages.Select(x => x.Id).ToList().ForEach(RecentMessages.Enqueue); if (messages.Any()) { me.LastSequenceNumber = messages.Last().SequenceNumber; } } var progress = InProgress.Select(x => x.Value).Where(x => !string.IsNullOrWhiteSpace(x)).ToList(); me.MakeReportForLeader(leadership, progress); session.SaveChanges(); } }