command.hpp
2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* Redis C++11 wrapper.
*/
#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <atomic>
#include <hiredis/adapters/libev.h>
#include <hiredis/async.h>
namespace redisx {
template<class ReplyT>
class Command {
friend class Redis;
public:
Command(
redisAsyncContext* c,
const std::string& cmd,
const std::function<void(const std::string&, const ReplyT&)>& callback,
const std::function<void(const std::string&, int status)>& error_callback,
double repeat, double after
);
const std::string cmd;
const double repeat;
const double after;
redisAsyncContext* c;
std::atomic_int pending;
void invoke(const ReplyT& reply);
void invoke_error(int status);
private:
const std::function<void(const std::string&, const ReplyT&)> callback;
const std::function<void(const std::string&, int status)>& error_callback;
std::atomic_bool completed;
ev_timer* timer;
std::mutex timer_guard;
ev_timer* get_timer() {
std::lock_guard<std::mutex> lg(timer_guard);
return timer;
}
};
template<class ReplyT>
Command<ReplyT>::Command(
redisAsyncContext* c,
const std::string& cmd,
const std::function<void(const std::string&, const ReplyT&)>& callback,
const std::function<void(const std::string&, int status)>& error_callback,
double repeat, double after
) : cmd(cmd), repeat(repeat), after(after), c(c), pending(0),
callback(callback), error_callback(error_callback), completed(false)
{
timer_guard.lock();
}
template<class ReplyT>
void Command<ReplyT>::invoke(const ReplyT& reply) {
if(callback != NULL) callback(cmd, reply);
pending--;
if((pending == 0) && (completed || (repeat == 0))) {
// std::cout << "invoking success, reply: " << reply << std::endl;
// std::cout << "Freeing cmd " << cmd << " in success invoke" << std::endl;
delete this;
}
}
template<class ReplyT>
void Command<ReplyT>::invoke_error(int status) {
if(error_callback != NULL) error_callback(cmd, status);
pending--;
if((pending == 0) && (completed || (repeat == 0))) {
// std::cout << "Freeing cmd " << cmd << " in error invoke" << std::endl;
delete this;
}
}
} // End namespace redis