Commit 3ea755c0f66227ce1620c41e1c33034cf1a2541a
1 parent
c0a7e596
Add syntax highlighting to README.md examples
Showing
1 changed file
with
81 additions
and
65 deletions
README.md
| ... | ... | @@ -49,23 +49,25 @@ This section introduces the main features of redox. Look in `examples/` for more |
| 49 | 49 | #### Hello world |
| 50 | 50 | Here is the simplest possible redox program: |
| 51 | 51 | |
| 52 | - #include <iostream> | |
| 53 | - #include <redox.hpp> | |
| 52 | +```c++ | |
| 53 | +#include <iostream> | |
| 54 | +#include <redox.hpp> | |
| 54 | 55 | |
| 55 | - using namespace std; | |
| 56 | - using namespace redox; | |
| 56 | +using namespace std; | |
| 57 | +using namespace redox; | |
| 57 | 58 | |
| 58 | - int main(int argc, char* argv[]) { | |
| 59 | +int main(int argc, char* argv[]) { | |
| 59 | 60 | |
| 60 | - Redox rdx; | |
| 61 | - if(!rdx.connect("localhost", 6379)) return 1; | |
| 61 | + Redox rdx; | |
| 62 | + if(!rdx.connect("localhost", 6379)) return 1; | |
| 62 | 63 | |
| 63 | - rdx.set("hello", "world!"); | |
| 64 | - cout << "Hello, " << rdx.get("hello") << endl; | |
| 64 | + rdx.set("hello", "world!"); | |
| 65 | + cout << "Hello, " << rdx.get("hello") << endl; | |
| 65 | 66 | |
| 66 | - rdx.disconnect(); | |
| 67 | - return 0; | |
| 68 | - } | |
| 67 | + rdx.disconnect(); | |
| 68 | + return 0; | |
| 69 | +} | |
| 70 | +``` | |
| 69 | 71 | |
| 70 | 72 | Compile and run: |
| 71 | 73 | |
| ... | ... | @@ -83,13 +85,15 @@ any Redis command and providing a reply callback. The `command` method accepts a |
| 83 | 85 | Redis command in the form of an STL vector of strings, and a callback to be invoked |
| 84 | 86 | when a reply is received or if there is an error. |
| 85 | 87 | |
| 86 | - rdx.command<string>({"GET", "hello"}, [](Command<string>& c) { | |
| 87 | - if(c.ok()) { | |
| 88 | - cout << "Hello, async " << c.reply() << endl; | |
| 89 | - } else { | |
| 90 | - cerr << "Command has error code " << c.status() << endl; | |
| 91 | - } | |
| 92 | - }); | |
| 88 | +```c++ | |
| 89 | +rdx.command<string>({"GET", "hello"}, [](Command<string>& c) { | |
| 90 | + if(c.ok()) { | |
| 91 | + cout << "Hello, async " << c.reply() << endl; | |
| 92 | + } else { | |
| 93 | + cerr << "Command has error code " << c.status() << endl; | |
| 94 | + } | |
| 95 | +}); | |
| 96 | +``` | |
| 93 | 97 | |
| 94 | 98 | This statement tells redox to run the command `GET hello`. The `<string>` template |
| 95 | 99 | parameter means that we want the reply to be put into a string and that we expect |
| ... | ... | @@ -109,43 +113,47 @@ the callback returns. |
| 109 | 113 | |
| 110 | 114 | Here is a simple example of running `GET hello` asynchronously ten times: |
| 111 | 115 | |
| 112 | - Redox rdx; | |
| 116 | +```c++ | |
| 117 | +Redox rdx; | |
| 113 | 118 | |
| 114 | - // Block until connected, localhost by default | |
| 115 | - if(!rdx.connect()) return 1; | |
| 119 | +// Block until connected, localhost by default | |
| 120 | +if(!rdx.connect()) return 1; | |
| 116 | 121 | |
| 117 | - auto got_reply = [](Command<string>& c) { | |
| 118 | - if(!c.ok()) return; | |
| 119 | - cout << c.cmd() << ": " << c.reply() << endl; | |
| 120 | - }; | |
| 122 | +auto got_reply = [](Command<string>& c) { | |
| 123 | + if(!c.ok()) return; | |
| 124 | + cout << c.cmd() << ": " << c.reply() << endl; | |
| 125 | +}; | |
| 121 | 126 | |
| 122 | - for(int i = 0; i < 10; i++) rdx.command<string>({"GET", "hello"}, got_reply); | |
| 127 | +for(int i = 0; i < 10; i++) rdx.command<string>({"GET", "hello"}, got_reply); | |
| 123 | 128 | |
| 124 | - // Do useful work | |
| 125 | - this_thread::sleep_for(chrono::milliseconds(10)); | |
| 129 | +// Do useful work | |
| 130 | +this_thread::sleep_for(chrono::milliseconds(10)); | |
| 126 | 131 | |
| 127 | - rdx.disconnect(); // Block until disconnected | |
| 132 | +rdx.disconnect(); // Block until disconnected | |
| 133 | +``` | |
| 128 | 134 | |
| 129 | 135 | The `.command()` method returns immediately, so this program doesn't wait for a reply |
| 130 | 136 | from the server - it just pauses for ten milliseconds and then shuts down. If we want to |
| 131 | 137 | shut down after we get all replies, we could do something like this: |
| 132 | 138 | |
| 133 | - Redox rdx; | |
| 134 | - if(!rdx.connect()) return 1; | |
| 139 | +```c++ | |
| 140 | +Redox rdx; | |
| 141 | +if(!rdx.connect()) return 1; | |
| 135 | 142 | |
| 136 | - int total = 10; // Number of commands to run | |
| 137 | - atomic_int count(0); // Number of replies expected | |
| 138 | - auto got_reply = [&](Command<string>& c) { | |
| 139 | - count++; | |
| 140 | - if(c.ok()) cout << c.cmd() << " #" << count << ": " << c.reply() << endl; | |
| 141 | - if(count == total) rdx.stop(); // Signal to shut down | |
| 142 | - }; | |
| 143 | +int total = 10; // Number of commands to run | |
| 144 | +atomic_int count(0); // Number of replies expected | |
| 145 | +auto got_reply = [&](Command<string>& c) { | |
| 146 | + count++; | |
| 147 | + if(c.ok()) cout << c.cmd() << " #" << count << ": " << c.reply() << endl; | |
| 148 | + if(count == total) rdx.stop(); // Signal to shut down | |
| 149 | +}; | |
| 143 | 150 | |
| 144 | - for(int i = 0; i < total; i++) rdx.command<string>({"GET", "hello"}, got_reply); | |
| 151 | +for(int i = 0; i < total; i++) rdx.command<string>({"GET", "hello"}, got_reply); | |
| 145 | 152 | |
| 146 | - // Do useful work | |
| 153 | +// Do useful work | |
| 147 | 154 | |
| 148 | - rdx.wait(); // Block until shut down complete | |
| 155 | +rdx.wait(); // Block until shut down complete | |
| 156 | +``` | |
| 149 | 157 | |
| 150 | 158 | This example tracks of how how many replies are received and signals the Redox |
| 151 | 159 | instance to stop once they all process. We use an `std::atomic_int` to be safe |
| ... | ... | @@ -162,9 +170,11 @@ between synchronous commands in different threads. The `commandSync` method prov |
| 162 | 170 | a similar API to `command`, but instead of a callback returns a Command object when |
| 163 | 171 | a reply is received. |
| 164 | 172 | |
| 165 | - Command<string>& c = rdx.commandSync<string>({"GET", "hello"}); | |
| 166 | - if(c.ok()) cout << c.cmd() << ": " << c.reply() << endl; | |
| 167 | - c.free(); | |
| 173 | +```c++ | |
| 174 | +Command<string>& c = rdx.commandSync<string>({"GET", "hello"}); | |
| 175 | +if(c.ok()) cout << c.cmd() << ": " << c.reply() << endl; | |
| 176 | +c.free(); | |
| 177 | +``` | |
| 168 | 178 | |
| 169 | 179 | When using synchronous commands, the user is responsible for freeing the memory of |
| 170 | 180 | the Command object by calling `c.free()`. The `c.cmd()` method just returns a string |
| ... | ... | @@ -178,22 +188,26 @@ commands in a loop, because it only creates a single Command object. |
| 178 | 188 | to repeat the command. It then runs the command on the given interval until the user |
| 179 | 189 | calls `c.free()`. |
| 180 | 190 | |
| 181 | - Command<string>& cmd = rdx.commandLoop<string>({"GET", "hello"}, [](Command<string>& c) { | |
| 182 | - if(c.ok()) cout << c.cmd() << ": " << c.reply() << endl; | |
| 183 | - }, 0.1); | |
| 191 | +```c++ | |
| 192 | +Command<string>& cmd = rdx.commandLoop<string>({"GET", "hello"}, [](Command<string>& c) { | |
| 193 | + if(c.ok()) cout << c.cmd() << ": " << c.reply() << endl; | |
| 194 | +}, 0.1); | |
| 184 | 195 | |
| 185 | - this_thread::sleep_for(chrono::seconds(1)); | |
| 186 | - cmd.free(); | |
| 187 | - rdx.disconnect(); | |
| 196 | +this_thread::sleep_for(chrono::seconds(1)); | |
| 197 | +cmd.free(); | |
| 198 | +rdx.disconnect(); | |
| 199 | +``` | |
| 188 | 200 | |
| 189 | 201 | Finally, `commandDelayed` runs a command after a specified delay (in seconds). It does |
| 190 | 202 | not return a command object, because the memory is automatically freed after the callback |
| 191 | 203 | is invoked. |
| 192 | 204 | |
| 193 | - rdx.commandDelayed<string>({"GET", "hello"}, [](Command<string>& c) { | |
| 194 | - if(c.ok()) cout << c.cmd() << ": " << c.reply() << endl; | |
| 195 | - }, 1); | |
| 196 | - this_thread::sleep_for(chrono::seconds(2)); | |
| 205 | +```c++ | |
| 206 | +rdx.commandDelayed<string>({"GET", "hello"}, [](Command<string>& c) { | |
| 207 | + if(c.ok()) cout << c.cmd() << ": " << c.reply() << endl; | |
| 208 | +}, 1); | |
| 209 | +this_thread::sleep_for(chrono::seconds(2)); | |
| 210 | +``` | |
| 197 | 211 | |
| 198 | 212 | #### Convenience methods |
| 199 | 213 | The four methods `command`, `commandSync`, `commandLoop`, and `commandDelayed` form |
| ... | ... | @@ -210,19 +224,21 @@ Redox provides an API for the pub/sub functionality of Redis. Publishing is done |
| 210 | 224 | any other command using a Redox instance. There is a separate Subscriber class that |
| 211 | 225 | receives messages and provides subscribe/unsubscribe and psubscribe/punsubscribe methods. |
| 212 | 226 | |
| 213 | - Redox rdx; Subscriber sub; | |
| 214 | - if(!rdx.connect() || !sub.connect()) return 1; | |
| 227 | +```c++ | |
| 228 | +Redox rdx; Subscriber sub; | |
| 229 | +if(!rdx.connect() || !sub.connect()) return 1; | |
| 215 | 230 | |
| 216 | - sub.subscribe("hello", [](const string& topic, const string& msg) { | |
| 217 | - cout << topic << ": " << msg << endl; | |
| 218 | - }); | |
| 231 | +sub.subscribe("hello", [](const string& topic, const string& msg) { | |
| 232 | + cout << topic << ": " << msg << endl; | |
| 233 | +}); | |
| 219 | 234 | |
| 220 | - for(int i = 0; i < 10; i++) { | |
| 221 | - rdx.publish("hello", "this is a pubsub message"); | |
| 222 | - this_thread::sleep_for(chrono::milliseconds(500)); | |
| 223 | - } | |
| 235 | +for(int i = 0; i < 10; i++) { | |
| 236 | + rdx.publish("hello", "this is a pubsub message"); | |
| 237 | + this_thread::sleep_for(chrono::milliseconds(500)); | |
| 238 | +} | |
| 224 | 239 | |
| 225 | - sub.disconnect(); rdx.disconnect(); | |
| 240 | +sub.disconnect(); rdx.disconnect(); | |
| 241 | +``` | |
| 226 | 242 | |
| 227 | 243 | #### strToVec and vecToStr |
| 228 | 244 | Redox provides helper methods to convert between a string command and | ... | ... |