1<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml">
4  <head>
5    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6    <title>Chapter 4. Replica versus Master Processes</title>
7    <link rel="stylesheet" href="gettingStarted.css" type="text/css" />
8    <meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
9    <link rel="home" href="index.html" title="Getting Started with Replicated Berkeley DB Applications" />
10    <link rel="up" href="index.html" title="Getting Started with Replicated Berkeley DB Applications" />
11    <link rel="previous" href="heartbeats.html" title="Managing Heartbeats" />
12    <link rel="next" href="processingloop.html" title="Processing Loop" />
13  </head>
14  <body>
15    <div class="navheader">
16      <table width="100%" summary="Navigation header">
17        <tr>
18          <th colspan="3" align="center">Chapter 4. Replica versus Master Processes</th>
19        </tr>
20        <tr>
21          <td width="20%" align="left"><a accesskey="p" href="heartbeats.html">Prev</a> </td>
22          <th width="60%" align="center"> </th>
23          <td width="20%" align="right"> <a accesskey="n" href="processingloop.html">Next</a></td>
24        </tr>
25      </table>
26      <hr />
27    </div>
28    <div class="chapter" lang="en" xml:lang="en">
29      <div class="titlepage">
30        <div>
31          <div>
32            <h2 class="title"><a id="fwrkmasterreplica"></a>Chapter 4. Replica versus Master Processes</h2>
33          </div>
34        </div>
35        <div></div>
36      </div>
37      <div class="toc">
38        <p>
39          <b>Table of Contents</b>
40        </p>
41        <dl>
42          <dt>
43            <span class="sect1">
44              <a href="fwrkmasterreplica.html#determinestate">Determining State</a>
45            </span>
46          </dt>
47          <dt>
48            <span class="sect1">
49              <a href="processingloop.html">Processing Loop</a>
50            </span>
51          </dt>
52          <dt>
53            <span class="sect1">
54              <a href="exampledoloop.html">Example Processing Loop</a>
55            </span>
56          </dt>
57          <dd>
58            <dl>
59              <dt>
60                <span class="sect2">
61                  <a href="exampledoloop.html#runningit">Running It</a>
62                </span>
63              </dt>
64            </dl>
65          </dd>
66        </dl>
67      </div>
68      <p>
69                  Every environment participating in a replicated application
70                  must know whether it is a <span class="emphasis"><em>master</em></span> or
71                  <span class="emphasis"><em>replica</em></span>. The reason for this is
72                  because, simply, the master can modify the database while
73                  replicas cannot. As a result, not only will you open
74                  databases differently depended on whether the environment is
75                  running as a master, but the environment will frequently
76                  behave quit a bit differently depending on whether it
77                  thinks it is operating as the read/write interface for
78                  your database.
79          </p>
80      <p>
81                  Moreover, an environment must also be capable of
82                  gracefully switching between master and replica states.
83                  This means that the environment must be able to detect when
84                  it has switched states.
85          </p>
86      <p>
87                  Not surprisingly, a large part of your application's code
88                  will be tied up in knowing which state a given
89                  environment is in and then in the logic of how to behave depending on
90                  its state.
91          </p>
92      <p>
93                  This chapter shows you how to determine your environment's
94                  state, and it then shows you some sample code on how
95                  an application might behave depending on whether it is a
96                  master or a replica in a replicated application.
97          </p>
98      <div class="sect1" lang="en" xml:lang="en">
99        <div class="titlepage">
100          <div>
101            <div>
102              <h2 class="title" style="clear: both"><a id="determinestate"></a>Determining State</h2>
103            </div>
104          </div>
105          <div></div>
106        </div>
107        <p>
108                          In order to determine whether your code is
109                          running as a master or a replica, you implement a
110                          callback whose function it is to respond to
111                          events that happen within the DB library. 
112                  </p>
113        <p>
114                          Note that this callback is usable for events beyond
115                          those required for replication purposes. In this
116                          section, however, we only discuss the
117                          replication-specific events.
118                  </p>
119        <p>
120                          The callback is required to determine
121                          which event has been passed to it, and then take
122                          action depending on the event. For replication,
123                          the events that we care about are:
124                  </p>
125        <div class="itemizedlist">
126          <ul type="disc">
127            <li>
128              <p>
129                                          <tt class="literal">DB_EVENT_REP_MASTER</tt>
130                                          
131                                  </p>
132              <p>
133                                          The local environment is now a master.
134                                  </p>
135            </li>
136            <li>
137              <p>
138                                          <tt class="literal">DB_EVENT_REP_CLIENT</tt>
139                                          
140                                  </p>
141              <p>
142                                          The local environment is now a replica.
143                                  </p>
144            </li>
145            <li>
146              <p>
147                                          <tt class="literal">DB_EVENT_REP_STARTUPDONE</tt>
148                                          
149                                  </p>
150              <p>
151                                          The replica has completed startup
152                                          synchronization and is now
153                                          processing log records received
154                                          from the master.
155                                  </p>
156            </li>
157            <li>
158              <p>
159                                          <tt class="literal">DB_EVENT_REP_NEWMASTER</tt>
160                                          
161                                  </p>
162              <p>
163                                          An election was held and a new
164                                          environment was made a master. However,
165                                          the current environment <span class="emphasis"><em>is
166                                          not</em></span> the master. This
167                                  event exists so that you can
168                                  cause your code to take some
169                                  unique action in the event that the
170                                  replication groups switches masters.
171                                  </p>
172            </li>
173          </ul>
174        </div>
175        <p>
176                          Note that these events are raised whenever the
177                          state is established. That is, when the current
178                          environment becomes a client, and that includes
179                          at application startup, the event is raised.
180                          Also, when an election is held and a client is elected to be a
181                          master, then the event occurs.
182                  </p>
183        <p>
184                          The implementation of this callback is fairly
185                          simple. First you pass a structure to the
186                          environment handle that you can use to record the
187                          environment's state, and then you implement a switch
188                          statement within the callback that you use to
189                          record the current state, depending on the
190                          arriving event.
191                  </p>
192        <p>
193                          For example:
194                  </p>
195        <pre class="programlisting">#include &lt;db_cxx.h&gt;
196/* Forward declaration */
197void *event_callback(DbEnv *, u_int32_t, void *);
198
199...
200
201/* The structure we use to track our environment's state */
202typedef struct {
203    int is_master;
204} APP_DATA;
205
206...
207
208/*
209 * Inside our main() function, we declare an APP_DATA variable.
210 */
211APP_DATA my_app_data;
212my_app_data.is_master = 0; /* Assume we start as a replica */
213
214...
215
216/*
217 * Now we open our environment handle and set the APP_DATA structure
218 * to it's app_private member.
219 */
220DbEnv *dbenv = new DbEnv(0);
221dbenv-&gt;set_app_private(&amp;my_app_data);
222
223/* Having done that, register the callback with the
224 * Berkeley DB library
225 */
226dbenv-&gt;set_event_notify(event_callback); </pre>
227        <p>
228        That done, we still need to implement the callback itself. This
229        implementation can be fairly trivial. 
230</p>
231        <pre class="programlisting">/*
232 * A callback used to determine whether the local environment is a replica
233 * or a master. This is called by the replication framework
234 * when the local environment changes state.
235 */
236void *
237event_callback(DbEnv *dbenv, u_int32_t which, void *info)
238{
239    APP_DATA *app = dbenv-&gt;get_app_private();
240
241    info = NULL;                /* Currently unused. */
242
243    switch (which) {
244    case DB_EVENT_REP_MASTER:
245        app-&gt;is_master = 1;
246        break;
247
248    case DB_EVENT_REP_CLIENT:
249        app-&gt;is_master = 0;
250        break;
251
252    case DB_EVENT_REP_STARTUPDONE: /* fallthrough */
253    case DB_EVENT_REP_NEWMASTER:
254        /* Ignore. */
255        break;
256
257    default:
258        dbenv-&gt;errx(dbenv, "ignoring event %d", which);
259    }
260} </pre>
261        <p>
262        Notice how we access the
263        <tt class="literal">APP_DATA</tt> information using the environment
264        handle's <tt class="literal">app_private</tt> data member. We also ignore
265        the <tt class="literal">DB_EVENT_REP_NEWMASTER</tt> and
266        <tt class="literal">DB_EVENT_REP_STARTUPDONE</tt> cases since these are not
267        relevant for simple replicated applications.
268</p>
269        <p>
270        Of course, this only gives us the current state of the environment. We
271        still need the code that determines what to do when the environment 
272        changes state and how to behave depending on the state (described
273        in the next section).
274</p>
275      </div>
276    </div>
277    <div class="navfooter">
278      <hr />
279      <table width="100%" summary="Navigation footer">
280        <tr>
281          <td width="40%" align="left"><a accesskey="p" href="heartbeats.html">Prev</a> </td>
282          <td width="20%" align="center">
283            <a accesskey="u" href="index.html">Up</a>
284          </td>
285          <td width="40%" align="right"> <a accesskey="n" href="processingloop.html">Next</a></td>
286        </tr>
287        <tr>
288          <td width="40%" align="left" valign="top">Managing Heartbeats </td>
289          <td width="20%" align="center">
290            <a accesskey="h" href="index.html">Home</a>
291          </td>
292          <td width="40%" align="right" valign="top"> Processing Loop</td>
293        </tr>
294      </table>
295    </div>
296  </body>
297</html>
298