public virtual async Task <long[]> Counts( string eventName, DateTime startTimestamp, DateTime endTimestamp, ActivityDrilldown drilldown) { Validation.ValidateEventName(eventName); var dates = startTimestamp.Range(endTimestamp, drilldown); var key = GenerateKey(eventName, drilldown.ToString()); var fields = dates.Select(d => GenerateTimeframeFields(drilldown, d) .ElementAt((int)drilldown)) .ToArray(); string[] values; using (var connection = await ConnectionFactories.Open()) { values = await connection.Hashes.GetString( Settings.Db, key, fields); } var result = values.Select(v => string.IsNullOrWhiteSpace(v) ? 0L : long.Parse(v)) .ToArray(); return(result); }
public virtual async Task Track( string eventName, ActivityDrilldown drilldown, DateTime timestamp, bool publishable, params long[] users) { Validation.ValidateEventName(eventName); Validation.ValidateUsers(users); string channel = null; byte[] payload = null; var timeframeKeys = GenerateEventTimeframeKeys( eventName, drilldown, timestamp).ToList(); var eventsKey = GenerateKey(); var db = Settings.Db; var tasks = new List <Task>(); if (publishable) { channel = eventsKey + Settings.KeySeparator + eventName.ToUpperInvariant(); payload = new UserActivitySubscriptionInfo { EventName = eventName, Timestamp = timestamp, Users = users }.Serialize(); } using (var connection = await ConnectionFactories.Open()) { foreach (var timeframeKey in timeframeKeys) { tasks.AddRange(users.Select(user => connection.Strings.SetBit( db, timeframeKey, user, true))); } tasks.Add(connection.Sets.Add(db, eventsKey, eventName)); await Task.WhenAll(tasks); if (publishable) { await connection.Publish(channel, payload); } } }
public virtual UserActivityReport Report( string eventName, ActivityDrilldown drilldown, DateTime timestamp) { Validation.ValidateEventName(eventName); var eventKey = GenerateEventTimeframeKeys( eventName, drilldown, timestamp).ElementAt((int)drilldown); return(new UserActivityReport(Settings.Db, eventKey)); }
public virtual async Task <long> Track( string eventName, ActivityDrilldown drilldown, DateTime timestamp, bool publishable) { Validation.ValidateEventName(eventName); var key = GenerateKey(eventName, drilldown.ToString()); var eventsKey = GenerateKey(); var fields = GenerateTimeframeFields(drilldown, timestamp).ToList(); var db = Settings.Db; using (var connection = await ConnectionFactories.Open()) { await connection.Sets.Add(db, eventsKey, eventName); var tasks = fields .Select(field => connection.Hashes .Increment(db, key, field)) .ToList(); var counts = await Task.WhenAll(tasks); var count = counts.ElementAt((int)drilldown); if (!publishable) { return(count); } var channel = eventsKey + Settings.KeySeparator + eventName.ToUpperInvariant(); var payload = new EventActivitySubscriptionInfo { EventName = eventName, Timestamp = timestamp, Drilldown = drilldown, Count = counts.ElementAt((int)drilldown) }.Serialize(); await connection.Publish(channel, payload); return(count); } }
public virtual ISubscription CreateSubscription( string eventName, Action <TInfo> action) { Validation.ValidateEventName(eventName); var channel = GenerateKey() + Settings.KeySeparator + eventName.ToUpperInvariant(); var subscription = new Subscription <TInfo>( ConnectionFactories.SubscriberFactory(), channel, action); return(subscription); }
public virtual async Task <IEnumerable <ActivityTimeframe> > Timeframes( string eventName) { Validation.ValidateEventName(eventName); var key = GenerateKey() + Settings.KeySeparator + eventName; string[] members; using (var connection = await ConnectionFactories.Open()) { members = await connection.Sets.GetAllString(Settings.Db, key); } var result = members.Select(m => (ActivityTimeframe)Enum.Parse(typeof(ActivityTimeframe), m)) .ToList(); return(result); }
public virtual async Task <long> Track( string eventName, ActivityTimeframe timeframe, DateTime timestamp, bool publishable) { // There are three tasks that we have to do here. // First, we have to maintain a list of events that has // been tracked, so that, the same event list can be // returned in the EventName method. Next. we also have to // maintain another list that is for time frames of the event, // please note that we are only going to maintain // the explicit timeframes, the Timeframes method returns the // explicit tracked timeframes for a given event name. // Second, increase the count for the matching timeframe. And at // last publish the event to redis so that the subscriber can be // notified. Validation.ValidateEventName(eventName); var eventsKey = GenerateKey(); var publishedEventsKey = eventsKey + Settings.KeySeparator + "published"; var key = GenerateKey(eventName, timeframe.ToString()); var fields = GenerateTimeframeFields(timeframe, timestamp).ToList(); var db = Settings.Db; using (var connection = await ConnectionFactories.Open()) { var eventTasks = new List <Task> { connection.Sets.Add(db, eventsKey, eventName), connection.Sets.Add( db, eventsKey + Settings.KeySeparator + eventName, timeframe.ToString()) }; if (publishable) { eventTasks.Add( connection.Sets.Add( db, publishedEventsKey, eventName)); } await Task.WhenAll(eventTasks); var fieldTasks = fields .Select(field => connection.Hashes .Increment(db, key, field)) .ToList(); var counts = await Task.WhenAll(fieldTasks); var count = counts.ElementAt((int)timeframe); if (!publishable) { return(count); } var channel = eventsKey + Settings.KeySeparator + eventName.ToUpperInvariant(); var payload = new EventActivitySubscriptionInfo { EventName = eventName, Timestamp = timestamp, Timeframe = timeframe, Count = counts.ElementAt((int)timeframe) }.Serialize(); await connection.Publish(channel, payload); return(count); } }
private string Channel(string eventName) { Validation.ValidateEventName(eventName); return(prefix + eventName.ToUpperInvariant()); }