change the controls to return a struct ctdb_client_control_state* instead of a handle
[sahlberg/ctdb.git] / libctdb / tst.c
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <poll.h>
5 #include <fcntl.h>
6 #include <string.h>
7 #include "lib/tdb/include/tdb.h"
8 #include "include/ctdb.h"
9
10 TDB_DATA key;
11
12 void msg_h(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA data, void *private_data)
13 {
14         printf("Message received on port 0x%016llx : %s\n", srvid, data.dptr);
15 }
16
17
18 void pnn_cb(int32_t status, struct ctdb_context *ctdb, struct ctdb_client_control_state *state, void *private_data)
19 {
20         uint32_t pnn;
21         int ret;
22
23         if (status != 0) {
24                 printf("Error reading PNN\n");
25                 return;
26         }
27
28         ret = ctdb_getpnn_recv(ctdb, state, &pnn);
29         if (ret != 0) {
30                 printf("Failed to read getpnn reply\n");
31                 return;
32         }
33
34         printf("status:%d pnn:%d\n", status, pnn);
35 }
36
37 void rm_cb(int32_t status, struct ctdb_context *ctdb, struct ctdb_client_control_state *state, void *private_data)
38 {
39         uint32_t rm;
40         int ret;
41
42         if (status != 0) {
43                 printf("Error reading RECMASTER\n");
44                 return;
45         }
46
47         ret = ctdb_getrecmaster_recv(ctdb, state, &rm);
48         if (ret != 0) {
49                 printf("Failed to read getpnn reply\n");
50                 return;
51         }
52
53         printf("GETRECMASTER ASYNC: status:%d recmaster:%d\n", status, rm);
54 }
55
56
57 /*
58  * example on how to first read(non-existing recortds are implicitely created
59  * on demand) a record and change it in the callback.
60  * This forms the atom for the read-modify-write cycle.
61  *
62  * Pure read, or pure write are just special cases of this cycle.
63  */
64 void rrl_cb(int32_t status, ctdb_handle *handle, TDB_DATA outdata, void *private_data)
65 {
66         TDB_DATA data;
67         char tmp[256];
68
69         if (status != 0) {
70                 printf("rrl_cb returned error: status %d\n", status);
71                 if (handle) {
72                         ctdb_free(handle);
73                 }
74                 return;
75         }
76
77         printf("rrl size:%d data:%s\n", outdata.dsize, outdata.dptr);
78         if (outdata.dsize == 0) {
79                 tmp[0] = 0;
80         } else {
81                 strcpy(tmp, outdata.dptr);
82         }
83         strcat(tmp, "*");
84
85         data.dptr  = tmp;
86         data.dsize = strlen(tmp) + 1;
87         ctdb_writerecord(handle, key, data);
88
89         printf("Wrote new record : %s\n", tmp);
90
91         ctdb_free(handle);
92 }
93
94
95
96
97 int main(int argc, char *argv[])
98 {
99         struct ctdb_context *ctdb;
100         struct ctdb_db_context *ctdb_db_context;
101         struct ctdb_client_control_state *control_state;
102         ctdb_handle *handle;
103         struct pollfd pfd;
104         int ret;
105         uint32_t recmaster;
106         TDB_DATA msg;
107
108         key.dptr  = "Test Record";
109         key.dsize = strlen(key.dptr);
110
111         ctdb = ctdb_connect("/tmp/ctdb.socket");
112
113         handle = ctdb_set_message_handler_send(ctdb, CTDB_SRVID_TEST|55, NULL, msg_h, NULL);
114         if (handle == NULL) {
115                 printf("Failed to register message port\n");
116                 exit(10);
117         }
118         ret = ctdb_set_message_handler_recv(ctdb, handle);
119         if (ret != 0) {
120                 printf("Failed to receive set_message_handler reply\n");
121                 exit(10);
122         }
123
124         msg.dptr="HelloWorld";
125         msg.dsize = strlen(msg.dptr);
126
127         ret = ctdb_send_message(ctdb, 0, CTDB_SRVID_TEST|55, msg);
128         if (ret != 0) {
129                 printf("Failed to send message. Aborting\n");
130                 exit(10);
131         }
132
133         handle = ctdb_attachdb_send(ctdb, "test_test.tdb", 0, 0, NULL, NULL);
134         if (handle == NULL) {
135                 printf("Failed to send attachdb control\n");
136                 exit(10);
137         }
138         ret = ctdb_attachdb_recv(ctdb, handle, &ctdb_db_context);
139         if (ret != 0 ) {
140                 printf("Failed to attach to database\n");
141                 exit(10);
142         }
143
144
145
146         /*
147          * ASYNC call with callback to read the recmaster
148          * this is the preferred way to use libctdb
149          */
150         control_state = ctdb_getrecmaster_send(ctdb, CTDB_CURRENT_NODE, rm_cb, NULL);
151         if (control_state == NULL) {
152                 printf("Failed to send get_recmaster control\n");
153                 exit(10);
154         }
155
156         /*
157          * SEMI-SYNC call with callback to read the recmaster
158          * calls the blocking *_recv() function.
159          * Avoid this mode for performance critical tasks
160          */
161         control_state = ctdb_getrecmaster_send(ctdb, CTDB_CURRENT_NODE, NULL, NULL);
162         if (control_state == NULL) {
163                 printf("Failed to send get_recmaster control\n");
164                 exit(10);
165         }
166         ret = ctdb_getrecmaster_recv(ctdb, control_state, &recmaster);
167         if (ret != 0) {
168                 printf("Failed to receive response to getrecmaster\n");
169                 exit(10);
170         }
171         printf("GETRECMASTER SEMI-SYNC: status:%d recmaster:%d\n", ret, recmaster);
172
173
174         /*
175          * SYNC call with callback to read the recmaster
176          * calls the blocking sync function.
177          * Avoid this mode for performance critical tasks
178          */
179         ret = ctdb_getrecmaster(ctdb, CTDB_CURRENT_NODE, &recmaster);
180         if (ret != 0) {
181                 printf("Failed to receive response to getrecmaster\n");
182                 exit(10);
183         }
184         printf("GETRECMASTER SYNC: status:%d recmaster:%d\n", ret, recmaster);
185
186
187
188
189         handle = ctdb_getpnn_send(ctdb, CTDB_CURRENT_NODE, pnn_cb, NULL);
190         if (handle == NULL) {
191                 printf("Failed to send get_pnn control\n");
192                 exit(10);
193         }
194
195
196
197         handle = ctdb_readrecordlock_send(ctdb, ctdb_db_context, key, rrl_cb, NULL);
198         if (handle == NULL) {
199                 printf("Failed to send READRECORDLOCK\n");
200                 exit(10);
201         }
202
203         pfd.fd = ctdb_get_fd(ctdb);
204         for (;;) {
205           pfd.events = ctdb_which_events(ctdb);
206           if (poll(&pfd, 1, -1) < 0) {
207             printf("Poll failed");
208             exit(10);
209           }
210           ctdb_service(ctdb);
211         }
212
213         return 0;
214 }