public virtual async Task <long[]> Counts( string eventName, DateTime startTimestamp, DateTime endTimestamp, ActivityTimeframe timeframe) { Validation.ValidateEventName(eventName); var dates = startTimestamp.Range(endTimestamp, timeframe); var key = GenerateKey(eventName, timeframe.ToString()); var fields = dates.Select(d => GenerateTimeframeFields(timeframe, d) .ElementAt((int)timeframe)) .ToArray(); string[] values; using (var connection = await ConnectionFactories.Open()) { values = await connection.Hashes.GetString( Settings.Db, key, fields); } var result = values.Select(value => value == null ? 0L : long.Parse(value)) .ToArray(); return(result); }
public virtual async Task Track( string eventName, ActivityTimeframe timeframe, DateTime timestamp, bool publishable, params long[] users) { Validation.ValidateEventName(eventName); Validation.ValidateUsers(users); var eventsKey = GenerateKey(); var publishedEventsKey = eventsKey + Settings.KeySeparator + "published"; string channel = null; byte[] payload = null; if (publishable) { channel = eventsKey + Settings.KeySeparator + eventName.ToUpperInvariant(); payload = new UserActivitySubscriptionInfo { EventName = eventName, Timestamp = timestamp, Timeframe = timeframe, Users = users }.Serialize(); } var timeframeKeys = GenerateEventTimeframeKeys( eventName, 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 bitTasks = new List <Task>(); foreach (var timeframeKey in timeframeKeys) { bitTasks.AddRange(users.Select(user => connection.Strings.SetBit( db, timeframeKey, user, true))); } await Task.WhenAll(bitTasks); if (publishable) { await connection.Publish(channel, payload); } } }
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); } }