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);
                }
            }
        }