271 lines
11 KiB
HTML
271 lines
11 KiB
HTML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||
<title>Chapter 4. Replica versus Master Processes</title>
|
||
<link rel="stylesheet" href="gettingStarted.css" type="text/css" />
|
||
<meta name="generator" content="DocBook XSL Stylesheets V1.62.4" />
|
||
<link rel="home" href="index.html" title="Getting Started with Replicated Berkeley DB Applications" />
|
||
<link rel="up" href="index.html" title="Getting Started with Replicated Berkeley DB Applications" />
|
||
<link rel="previous" href="heartbeats.html" title="Managing Heartbeats" />
|
||
<link rel="next" href="processingloop.html" title="Processing Loop" />
|
||
</head>
|
||
<body>
|
||
<div class="navheader">
|
||
<table width="100%" summary="Navigation header">
|
||
<tr>
|
||
<th colspan="3" align="center">Chapter 4. Replica versus Master Processes</th>
|
||
</tr>
|
||
<tr>
|
||
<td width="20%" align="left"><a accesskey="p" href="heartbeats.html">Prev</a> </td>
|
||
<th width="60%" align="center"> </th>
|
||
<td width="20%" align="right"> <a accesskey="n" href="processingloop.html">Next</a></td>
|
||
</tr>
|
||
</table>
|
||
<hr />
|
||
</div>
|
||
<div class="chapter" lang="en" xml:lang="en">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h2 class="title"><a id="fwrkmasterreplica"></a>Chapter 4. Replica versus Master Processes</h2>
|
||
</div>
|
||
</div>
|
||
<div></div>
|
||
</div>
|
||
<div class="toc">
|
||
<p>
|
||
<b>Table of Contents</b>
|
||
</p>
|
||
<dl>
|
||
<dt>
|
||
<span class="sect1">
|
||
<a href="fwrkmasterreplica.html#determinestate">Determining State</a>
|
||
</span>
|
||
</dt>
|
||
<dt>
|
||
<span class="sect1">
|
||
<a href="processingloop.html">Processing Loop</a>
|
||
</span>
|
||
</dt>
|
||
<dt>
|
||
<span class="sect1">
|
||
<a href="exampledoloop.html">Example Processing Loop</a>
|
||
</span>
|
||
</dt>
|
||
<dd>
|
||
<dl>
|
||
<dt>
|
||
<span class="sect2">
|
||
<a href="exampledoloop.html#runningit">Running It</a>
|
||
</span>
|
||
</dt>
|
||
</dl>
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
<p>
|
||
Every environment participating in a replicated application
|
||
must know whether it is a <span class="emphasis"><em>master</em></span> or
|
||
<span class="emphasis"><em>replica</em></span>. The reason for this is
|
||
because, simply, the master can modify the database while
|
||
replicas cannot. As a result, not only will you open
|
||
databases differently depended on whether the environment is
|
||
running as a master, but the environment will frequently
|
||
behave quit a bit differently depending on whether it
|
||
thinks it is operating as the read/write interface for
|
||
your database.
|
||
</p>
|
||
<p>
|
||
Moreover, an environment must also be capable of
|
||
gracefully switching between master and replica states.
|
||
This means that the environment must be able to detect when
|
||
it has switched states.
|
||
</p>
|
||
<p>
|
||
Not surprisingly, a large part of your application's code
|
||
will be tied up in knowing which state a given
|
||
environment is in and then in the logic of how to behave depending on
|
||
its state.
|
||
</p>
|
||
<p>
|
||
This chapter shows you how to determine your environment's
|
||
state, and it then shows you some sample code on how
|
||
an application might behave depending on whether it is a
|
||
master or a replica in a replicated application.
|
||
</p>
|
||
<div class="sect1" lang="en" xml:lang="en">
|
||
<div class="titlepage">
|
||
<div>
|
||
<div>
|
||
<h2 class="title" style="clear: both"><a id="determinestate"></a>Determining State</h2>
|
||
</div>
|
||
</div>
|
||
<div></div>
|
||
</div>
|
||
<p>
|
||
In order to determine whether your code is running
|
||
as a master or a replica, you must write your
|
||
application as an implementation of
|
||
<tt class="classname">com.sleepycat.db.EventHandler</tt>.
|
||
This class gives you a single method,
|
||
<tt class="methodname">handleEvent()</tt>, within
|
||
which you can detect and respond to various events
|
||
that occur in your DB code.
|
||
</p>
|
||
<p>
|
||
Note that <tt class="methodname">EventHandler</tt>
|
||
responds to a number of
|
||
<tt class="classname">com.sleepycat.db.EventType</tt>
|
||
events, only some of which are related to
|
||
replication. For replication, the events that we
|
||
care about are:
|
||
</p>
|
||
<div class="itemizedlist">
|
||
<ul type="disc">
|
||
<li>
|
||
<p>
|
||
|
||
<tt class="literal">EventType.REP_MASTER</tt>
|
||
</p>
|
||
<p>
|
||
The local environment is now a master.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
|
||
<tt class="literal">EventType.REP_CLIENT</tt>
|
||
</p>
|
||
<p>
|
||
The local environment is now a replica.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
|
||
<tt class="literal">EventType.REP_STARTUPDONE</tt>
|
||
</p>
|
||
<p>
|
||
The replica has completed startup
|
||
synchronization and is now
|
||
processing log records received
|
||
from the master.
|
||
</p>
|
||
</li>
|
||
<li>
|
||
<p>
|
||
|
||
<tt class="literal">EventType.REP_NEWMASTER</tt>
|
||
</p>
|
||
<p>
|
||
An election was held and a new
|
||
environment was made a master. However,
|
||
the current environment <span class="emphasis"><em>is
|
||
not</em></span> the master. This
|
||
event exists so that you can
|
||
cause your code to take some
|
||
unique action in the event that the
|
||
replication groups switches masters.
|
||
</p>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<p>
|
||
Note that these events are raised whenever the
|
||
state is established. That is, when the current
|
||
environment becomes a client, and that includes
|
||
at application startup, the event is raised.
|
||
Also, when an election is held and a client is elected to be a
|
||
master, then the event occurs.
|
||
</p>
|
||
<p>
|
||
The <tt class="classname">EventHandler</tt>
|
||
implementation is fairly simple. First you detect
|
||
the event, and then you record the state change
|
||
in some data member maintained in a location that
|
||
is convenient to you.
|
||
</p>
|
||
<p>
|
||
For example:
|
||
</p>
|
||
<pre class="programlisting">
|
||
package db.repquote;
|
||
|
||
// We make our main class an EventHandler implementation
|
||
...
|
||
import com.sleepycat.db.EventHandler;
|
||
...
|
||
|
||
public class MyReplicationClass implements EventHandler
|
||
{
|
||
|
||
...
|
||
|
||
// Somewhere we provide a data member that is used to track
|
||
// whether we are a master server. This could be in our main
|
||
// class, or it could be part of a supporting class.
|
||
private boolean isMaster;
|
||
|
||
...
|
||
|
||
isMaster = false;
|
||
|
||
...
|
||
|
||
// In the code where we open our environment and start replication,
|
||
// we must identify the class that is the event handler. In this
|
||
// example, we are performing this from within the class that
|
||
// implements com.sleepycat.db.EventHandler so we identify
|
||
// "this" class as the event handler
|
||
envConfig.setEventHandler(this); </pre>
|
||
<p>
|
||
That done, we still need to implement the <tt class="methodname">handleEvent</tt>
|
||
method. This implementation can be fairly trivial.
|
||
</p>
|
||
<pre class="programlisting"> public int handleEvent(EventType event)
|
||
{
|
||
int ret = 0;
|
||
if (event == EventType.REP_MASTER)
|
||
dbenv.setIsMaster(true);
|
||
else if (event == EventType.REP_CLIENT)
|
||
dbenv.setIsMaster(false);
|
||
else if (event == EventType.REP_NEW_MASTER) {
|
||
// ignored for now.
|
||
} else {
|
||
System.err.println("Unknown event callback received.\n");
|
||
ret = 1;
|
||
}
|
||
return ret;
|
||
} </pre>
|
||
<p>
|
||
Of course, this only gives us the current state of the environment. We
|
||
still need the code that determines what to do when the environment
|
||
changes state and how to behave depending on the state (described
|
||
in the next section).
|
||
</p>
|
||
</div>
|
||
</div>
|
||
<div class="navfooter">
|
||
<hr />
|
||
<table width="100%" summary="Navigation footer">
|
||
<tr>
|
||
<td width="40%" align="left"><a accesskey="p" href="heartbeats.html">Prev</a> </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="u" href="index.html">Up</a>
|
||
</td>
|
||
<td width="40%" align="right"> <a accesskey="n" href="processingloop.html">Next</a></td>
|
||
</tr>
|
||
<tr>
|
||
<td width="40%" align="left" valign="top">Managing Heartbeats </td>
|
||
<td width="20%" align="center">
|
||
<a accesskey="h" href="index.html">Home</a>
|
||
</td>
|
||
<td width="40%" align="right" valign="top"> Processing Loop</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
</body>
|
||
</html>
|