public void SetJobState(string jobId, State state)
        {
            _transaction.QueueCommand(x => x.SetEntryInHash(
                String.Format(RedisStorage.Prefix + "job:{0}", jobId),
                "State",
                state.Name));

            _transaction.QueueCommand(x => x.RemoveEntry(
                String.Format(RedisStorage.Prefix + "job:{0}:state", jobId)));

            // Redis does not provide repeatable read functionality,
            // so job state might be changed between reads of the job
            // state itself and a data of the state. In monitoring API
            // we don't show state data when data.State !== job.State.
            var storedData = new Dictionary<string, string>(state.Serialize());
            storedData.Add("State", state.Name);

            if (state.Reason != null)
            {
                storedData.Add("Reason", state.Reason);
            }

            _transaction.QueueCommand(x => x.SetRangeInHash(
                String.Format(RedisStorage.Prefix + "job:{0}:state", jobId),
                storedData));

            AddJobState(jobId, state);
        }
        public void AddJobState(string jobId, State state)
        {
            const string addStateSql = @"
insert into HangFire.State (JobId, Name, Reason, CreatedAt, Data)
values (@jobId, @name, @reason, @createdAt, @data)";

            QueueCommand(x => x.Execute(
                addStateSql,
                new
                {
                    jobId = jobId, 
                    name = state.Name,
                    reason = state.Reason,
                    createdAt = DateTime.UtcNow, 
                    data = JobHelper.ToJson(state.Serialize())
                }));
        }
        public void AddJobState(string jobId, State state)
        {
            // We are storing some more information in the same key,
            // let's add it.
            var storedData = new Dictionary<string, string>(state.Serialize());
            storedData.Add("State", state.Name);
            storedData.Add("Reason", state.Reason);
            storedData.Add("CreatedAt", JobHelper.ToStringTimestamp(DateTime.UtcNow));

            _transaction.QueueCommand(x => x.EnqueueItemOnList(
                String.Format(RedisStorage.Prefix + "job:{0}:history", jobId),
                JobHelper.ToJson(storedData)));
        }
        public void SetJobState(string jobId, State state)
        {
            const string addAndSetStateSql = @"
insert into HangFire.State (JobId, Name, Reason, CreatedAt, Data)
values (@jobId, @name, @reason, @createdAt, @data);
update HangFire.Job set StateId = SCOPE_IDENTITY(), StateName = @name where Id = @id;";

            QueueCommand(x => x.Execute(
                addAndSetStateSql,
                new
                {
                    jobId = jobId,
                    name = state.Name,
                    reason = state.Reason,
                    createdAt = DateTime.UtcNow,
                    data = JobHelper.ToJson(state.Serialize()),
                    id = jobId
                }));
        }