Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpnehrer2005-05-02 04:18:27 +0000
committerpnehrer2005-05-02 04:18:27 +0000
commit93a39c2983ae889ee07a62fb9a3868733ec55ecb (patch)
treeccb33f090c935fd20a4a879a6303d1fbdf818100
parent03f151c14b1923630d386dc2e2e26d009d19dbc2 (diff)
downloadorg.eclipse.ecf-93a39c2983ae889ee07a62fb9a3868733ec55ecb.tar.gz
org.eclipse.ecf-93a39c2983ae889ee07a62fb9a3868733ec55ecb.tar.xz
org.eclipse.ecf-93a39c2983ae889ee07a62fb9a3868733ec55ecb.zip
Checkpoint.
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Agent.java62
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/EagerElectionBootstrap.java360
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrap.java22
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrapMemento.java22
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/LazyElectionBootstrap.java278
-rw-r--r--framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/ServerBootstrap.java102
6 files changed, 500 insertions, 346 deletions
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Agent.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Agent.java
index e2c6a85be..55d55a9ef 100644
--- a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Agent.java
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/Agent.java
@@ -11,6 +11,7 @@
package org.eclipse.ecf.internal.datashare;
import java.io.IOException;
+import java.util.HashMap;
import java.util.Map;
import org.eclipse.ecf.core.ISharedObject;
@@ -44,11 +45,14 @@ public class Agent implements ISharedData, ISharedObject {
private IPublicationCallback pubCallback;
+ private Version version;
+
public Agent() {
}
- public Agent(Object sharedData) {
+ public Agent(Object sharedData, IBootstrap bootstrap) {
this.sharedData = sharedData;
+ this.bootstrap = bootstrap;
}
public synchronized ID getID() {
@@ -60,6 +64,17 @@ public class Agent implements ISharedData, ISharedObject {
}
public synchronized void commit() throws ECFException {
+ byte[] buf = updateProvider.createUpdate(this);
+ if (buf != null) {
+ Version newVersion = version.getNext(config.getSharedObjectID());
+ Update update = new Update(newVersion, buf);
+ version = newVersion;
+ try {
+ config.getContext().sendMessage(null, update);
+ } catch (IOException e) {
+ throw new ECFException(e);
+ }
+ }
}
public synchronized void dispose() {
@@ -81,10 +96,17 @@ public class Agent implements ISharedData, ISharedObject {
throws SharedObjectInitException {
this.config = config;
Map params = config.getProperties();
- if (params != null)
+ if (params != null) {
sharedData = params.get("sharedData");
+ version = (Version) params.get("version");
+ IBootstrapMemento m = (IBootstrapMemento) params.get("bootstrap");
+ if (m != null)
+ bootstrap = m.createBootstrap();
+ }
+
+ if (version == null)
+ version = new Version(config.getSharedObjectID());
- bootstrap = new LazyElectionBootstrap();
bootstrap.setAgent(this);
bootstrap.init(config);
}
@@ -95,6 +117,7 @@ public class Agent implements ISharedData, ISharedObject {
* @see org.eclipse.ecf.core.ISharedObject#handleEvent(org.eclipse.ecf.core.util.Event)
*/
public void handleEvent(Event event) {
+ bootstrap.handleEvent(event);
if (event instanceof ISharedObjectActivatedEvent) {
ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
if (e.getActivatedID().equals(config.getSharedObjectID()))
@@ -104,19 +127,20 @@ public class Agent implements ISharedData, ISharedObject {
if (e.getData() instanceof Update)
handleUpdate((Update) e.getData());
}
-
- bootstrap.handleEvent(event);
}
private void handleActivated() {
if (config.getHomeContainerID().equals(
config.getContext().getLocalContainerID()))
try {
+ Map params = new HashMap(3);
+ params.put("sharedData", sharedData);
+ params.put("version", version);
+ params.put("bootstrap", bootstrap.createMemento());
config.getContext().sendCreate(
null,
new SharedObjectDescription(config.getSharedObjectID(),
- getClass()));
-
+ getClass(), params));
if (pubCallback != null)
pubCallback.dataPublished(this);
} catch (IOException e) {
@@ -127,13 +151,29 @@ public class Agent implements ISharedData, ISharedObject {
pubCallback = null;
}
}
-
- private void handleUpdate(Update upate) {
- // TODO implement me!
+
+ private void handleUpdate(Update update) {
+ try {
+ updateProvider.applyUpdate(this, update.getData());
+ version = update.getVersion();
+ } catch (ECFException e) {
+ handleError(e);
+ }
}
public void doBootstrap(ID containerID) {
- // TODO bootstrap the new member
+ Map params = new HashMap(3);
+ params.put("sharedData", sharedData);
+ params.put("version", version);
+ params.put("bootstrap", bootstrap.createMemento());
+ try {
+ config.getContext().sendCreate(
+ containerID,
+ new SharedObjectDescription(config.getSharedObjectID(),
+ getClass(), params));
+ } catch (IOException e) {
+ handleError(e);
+ }
}
private void handleError(Throwable t) {
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/EagerElectionBootstrap.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/EagerElectionBootstrap.java
index 1a425401a..f3181ac2c 100644
--- a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/EagerElectionBootstrap.java
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/EagerElectionBootstrap.java
@@ -31,171 +31,197 @@ import org.eclipse.ecf.core.util.Event;
*/
public class EagerElectionBootstrap implements IBootstrap {
- private final Random random = new Random();
-
- private Agent agent;
-
- private ISharedObjectConfig config;
-
- private ID coordinatorID;
-
- private Election election;
-
- private final Timer timer = new Timer();
-
- private TimerTask task;
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#setAgent(org.eclipse.ecf.internal.datashare.Agent)
- */
- public void setAgent(Agent agent) {
- this.agent = agent;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#init(org.eclipse.ecf.core.ISharedObjectConfig)
- */
- public void init(ISharedObjectConfig config)
- throws SharedObjectInitException {
- this.config = config;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#handleEvent(org.eclipse.ecf.core.util.Event)
- */
- public void handleEvent(Event event) {
- if (event instanceof ISharedObjectActivatedEvent) {
- ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
- if (e.getActivatedID().equals(config.getSharedObjectID()))
- handleActivated();
- } else if (event instanceof ISharedObjectContainerJoinedEvent) {
- ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
- if (!e.getJoinedContainerID().equals(e.getLocalContainerID()))
- handleJoined(e.getJoinedContainerID());
- } else if (event instanceof ISharedObjectContainerDepartedEvent) {
- ISharedObjectContainerDepartedEvent e = (ISharedObjectContainerDepartedEvent) event;
- if (!e.getDepartedContainerID().equals(e.getLocalContainerID()))
- handleDeparted(e.getDepartedContainerID());
- } else if (event instanceof ISharedObjectMessageEvent) {
- ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
- if (e.getData() instanceof Vote)
- handleVote((Vote) e.getData(), e.getRemoteContainerID());
- else if (e.getData() instanceof Elected)
- handleElected(e.getRemoteContainerID());
- else if (e.getData() instanceof Ping)
- handlePing();
- }
- }
-
- private synchronized void handleActivated() {
- if (config.getHomeContainerID().equals(
- config.getContext().getLocalContainerID())) {
- coordinatorID = config.getContext().getLocalContainerID();
- timer.schedule(task = new Pinger(), 1000, 1000); // TODO make configurable
- } else {
- timer.schedule(task = new PingWatch(), 2000); // TODO make configurable
- }
- }
-
- private synchronized void handleJoined(ID containerID) {
- // TODO what if election is pending?
- if (config.getContext().getLocalContainerID().equals(coordinatorID))
- agent.doBootstrap(containerID);
- }
-
- private synchronized void handleVote(Vote msg, ID containerID) {
- if (election != null) {
- switch (election.processVote(msg.getTicket(), containerID)) {
- case Election.WON:
- processVictory();
- case Election.LOST:
- election = null;
- }
- }
- }
-
- private synchronized void handleElected(ID containerID) {
- election = null;
- coordinatorID = containerID;
- timer.schedule(task = new PingWatch(), 2000);
- }
-
- private synchronized void handleDeparted(ID containerID) {
- if (containerID.equals(coordinatorID))
- startElection();
- }
-
- private void handlePing() {
- if (task != null)
- task.cancel();
-
- timer.schedule(task = new PingWatch(), 2000);
- }
-
- private synchronized void startElection() {
- if (task != null)
- task.cancel();
-
- List members = Arrays.asList(config.getContext().getGroupMemberIDs());
- members.remove(config.getContext().getLocalContainerID());
- if (members.isEmpty())
- processVictory();
- else {
- long ticket = random.nextLong(); // TODO strategize this
- election = new Election(ticket, members);
- try {
- config.getContext().sendMessage(null, new Vote(ticket, null));
- } catch (IOException e) {
- handleError(e);
- }
- }
- }
-
- private void processVictory() {
- try {
- config.getContext().sendMessage(null, new Elected(null));
- coordinatorID = config.getContext().getLocalContainerID();
- timer.schedule(task = new Pinger(), 1000, 1000);
- } catch (IOException e) {
- handleError(e);
- }
- }
-
- private void handleError(Throwable t) {
- t.printStackTrace();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#dispose(org.eclipse.ecf.core.identity.ID)
- */
- public void dispose(ID containerID) {
- timer.cancel();
- config = null;
- }
-
- private class Pinger extends TimerTask {
-
- public void run() {
- try {
- config.getContext().sendMessage(null, new Ping());
- } catch (IOException e) {
- handleError(e);
- }
- }
- }
-
- private class PingWatch extends TimerTask {
-
- public void run() {
- startElection();
- }
- }
+ private final Random random = new Random();
+
+ private Agent agent;
+
+ private ISharedObjectConfig config;
+
+ private ID coordinatorID;
+
+ private Election election;
+
+ private final Timer timer = new Timer();
+
+ private TimerTask task;
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#setAgent(org.eclipse.ecf.internal.datashare.Agent)
+ */
+ public void setAgent(Agent agent) {
+ this.agent = agent;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#init(org.eclipse.ecf.core.ISharedObjectConfig)
+ */
+ public void init(ISharedObjectConfig config)
+ throws SharedObjectInitException {
+ this.config = config;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#handleEvent(org.eclipse.ecf.core.util.Event)
+ */
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectActivatedEvent) {
+ ISharedObjectActivatedEvent e = (ISharedObjectActivatedEvent) event;
+ if (e.getActivatedID().equals(config.getSharedObjectID()))
+ handleActivated();
+ } else if (event instanceof ISharedObjectContainerJoinedEvent) {
+ ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
+ if (!e.getJoinedContainerID().equals(e.getLocalContainerID()))
+ handleJoined(e.getJoinedContainerID());
+ } else if (event instanceof ISharedObjectContainerDepartedEvent) {
+ ISharedObjectContainerDepartedEvent e = (ISharedObjectContainerDepartedEvent) event;
+ if (!e.getDepartedContainerID().equals(e.getLocalContainerID()))
+ handleDeparted(e.getDepartedContainerID());
+ } else if (event instanceof ISharedObjectMessageEvent) {
+ ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
+ if (e.getData() instanceof Vote)
+ handleVote((Vote) e.getData(), e.getRemoteContainerID());
+ else if (e.getData() instanceof Elected)
+ handleElected(e.getRemoteContainerID());
+ else if (e.getData() instanceof Ping)
+ handlePing();
+ }
+ }
+
+ private synchronized void handleActivated() {
+ if (config.getHomeContainerID().equals(
+ config.getContext().getLocalContainerID())) {
+ coordinatorID = config.getContext().getLocalContainerID();
+ timer.schedule(task = new Pinger(), 1000, 1000); // TODO make configurable
+ } else {
+ timer.schedule(task = new PingWatch(), 2000); // TODO make configurable
+ }
+ }
+
+ private synchronized void handleJoined(ID containerID) {
+ // TODO what if election is pending?
+ if (config.getContext().getLocalContainerID().equals(coordinatorID))
+ agent.doBootstrap(containerID);
+ }
+
+ private synchronized void handleVote(Vote msg, ID containerID) {
+ if (election != null) {
+ switch (election.processVote(msg.getTicket(), containerID)) {
+ case Election.WON:
+ processVictory();
+ case Election.LOST:
+ election = null;
+ }
+ }
+ }
+
+ private synchronized void handleElected(ID containerID) {
+ election = null;
+ coordinatorID = containerID;
+ timer.schedule(task = new PingWatch(), 2000);
+ }
+
+ private synchronized void handleDeparted(ID containerID) {
+ if (containerID.equals(coordinatorID))
+ startElection();
+ }
+
+ private void handlePing() {
+ if (task != null)
+ task.cancel();
+
+ timer.schedule(task = new PingWatch(), 2000);
+ }
+
+ private synchronized void startElection() {
+ if (task != null)
+ task.cancel();
+
+ List members = Arrays.asList(config.getContext().getGroupMemberIDs());
+ members.remove(config.getContext().getLocalContainerID());
+ if (members.isEmpty())
+ processVictory();
+ else {
+ long ticket = random.nextLong(); // TODO strategize this
+ election = new Election(ticket, members);
+ try {
+ config.getContext().sendMessage(null, new Vote(ticket, null));
+ } catch (IOException e) {
+ handleError(e);
+ }
+ }
+ }
+
+ private void processVictory() {
+ try {
+ config.getContext().sendMessage(null, new Elected(null));
+ coordinatorID = config.getContext().getLocalContainerID();
+ timer.schedule(task = new Pinger(), 1000, 1000);
+ } catch (IOException e) {
+ handleError(e);
+ }
+ }
+
+ private void handleError(Throwable t) {
+ t.printStackTrace();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#dispose(org.eclipse.ecf.core.identity.ID)
+ */
+ public void dispose(ID containerID) {
+ timer.cancel();
+ config = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#createMemento()
+ */
+ public IBootstrapMemento createMemento() {
+ return new BootstrapMemento(coordinatorID);
+ }
+
+ private class Pinger extends TimerTask {
+
+ public void run() {
+ try {
+ config.getContext().sendMessage(null, new Ping());
+ } catch (IOException e) {
+ handleError(e);
+ }
+ }
+ }
+
+ private class PingWatch extends TimerTask {
+
+ public void run() {
+ startElection();
+ }
+ }
+
+ public static class BootstrapMemento implements IBootstrapMemento {
+
+ private static final long serialVersionUID = 3257562910522814772L;
+
+ private final ID coordinatorID;
+
+ private BootstrapMemento(ID coordinatorID) {
+ this.coordinatorID = coordinatorID;
+ }
+
+ public IBootstrap createBootstrap() {
+ EagerElectionBootstrap b = new EagerElectionBootstrap();
+ b.coordinatorID = this.coordinatorID;
+ return b;
+ }
+ }
}
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrap.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrap.java
index bab96abc3..8e5fa1b42 100644
--- a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrap.java
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrap.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * Copyright (c) 2005 Peter Nehrer and Composent, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Peter Nehrer - initial API and implementation
+ *******************************************************************************/
package org.eclipse.ecf.internal.datashare;
import org.eclipse.ecf.core.ISharedObjectConfig;
@@ -5,14 +15,18 @@ import org.eclipse.ecf.core.SharedObjectInitException;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.core.util.Event;
+/**
+ * @author pnehrer
+ */
public interface IBootstrap {
- void setAgent(Agent agent);
+ void setAgent(Agent agent);
- void init(ISharedObjectConfig config) throws SharedObjectInitException;
+ void init(ISharedObjectConfig config) throws SharedObjectInitException;
- void handleEvent(Event event);
+ void handleEvent(Event event);
- void dispose(ID containerID);
+ void dispose(ID containerID);
+ IBootstrapMemento createMemento();
} \ No newline at end of file
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrapMemento.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrapMemento.java
new file mode 100644
index 000000000..f1eb5dce3
--- /dev/null
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/IBootstrapMemento.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2005 Peter Nehrer and Composent, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Peter Nehrer - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.ecf.internal.datashare;
+
+import java.io.Serializable;
+
+/**
+ * @author pnehrer
+ *
+ */
+public interface IBootstrapMemento extends Serializable {
+
+ IBootstrap createBootstrap();
+}
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/LazyElectionBootstrap.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/LazyElectionBootstrap.java
index 7a9c52769..923bf5cf1 100644
--- a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/LazyElectionBootstrap.java
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/LazyElectionBootstrap.java
@@ -31,130 +31,156 @@ import org.eclipse.ecf.core.util.Event;
*/
public class LazyElectionBootstrap implements IBootstrap {
- private final Random random = new Random();
-
- private Agent agent;
-
- private ISharedObjectConfig config;
-
- private final HashMap elections = new HashMap();
-
- /* (non-Javadoc)
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#setAgent(org.eclipse.ecf.internal.datashare.Agent)
- */
- public void setAgent(Agent agent) {
- this.agent = agent;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#init(org.eclipse.ecf.core.ISharedObjectConfig)
- */
- public void init(ISharedObjectConfig config)
- throws SharedObjectInitException {
- this.config = config;
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#handleEvent(org.eclipse.ecf.core.util.Event)
- */
- public void handleEvent(Event event) {
- if (event instanceof ISharedObjectContainerJoinedEvent) {
- ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
- if (!e.getJoinedContainerID().equals(e.getLocalContainerID()))
- handleJoined(e.getJoinedContainerID());
- } else if (event instanceof ISharedObjectContainerDepartedEvent) {
- ISharedObjectContainerDepartedEvent e = (ISharedObjectContainerDepartedEvent) event;
- if (!e.getDepartedContainerID().equals(e.getLocalContainerID()))
- handleDeparted(e.getDepartedContainerID());
- } else if (event instanceof ISharedObjectMessageEvent) {
- ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
- if (e.getData() instanceof Vote)
- handleVote((Vote) e.getData(), e.getRemoteContainerID());
- else if (e.getData() instanceof Elected)
- handleElected((Elected) e.getData());
- }
- }
-
- private void handleJoined(ID containerID) {
- List members = Arrays.asList(config.getContext().getGroupMemberIDs());
- members.remove(containerID);
- members.remove(config.getContext().getLocalContainerID());
- if (members.isEmpty())
- processVictory(containerID);
- else {
- long ticket = random.nextLong(); // TODO strategize this
- Election election = new Election(ticket, members);
- synchronized (elections) {
- elections.put(containerID, election);
- }
-
- try {
- config.getContext().sendMessage(null,
- new Vote(ticket, containerID));
- } catch (IOException e) {
- handleError(e);
- }
- }
- }
-
- private void handleVote(Vote msg, ID containerID) {
- synchronized (elections) {
- Election election = (Election) elections.get(msg.getElectionID());
- if (election != null) {
- switch (election.processVote(msg.getTicket(), containerID)) {
- case Election.WON:
- processVictory(msg.getElectionID());
- case Election.LOST:
- elections.remove(msg.getElectionID());
- }
- }
- }
- }
-
- private void handleElected(Elected msg) {
- synchronized (elections) {
- elections.remove(msg.getElectionID());
- }
- }
-
- private void handleDeparted(ID containerID) {
- synchronized (elections) {
- for (Iterator i = elections.entrySet().iterator(); i.hasNext();) {
- Map.Entry entry = (Map.Entry) i.next();
- ID electionID = (ID) entry.getKey();
- if (containerID.equals(electionID))
- i.remove();
- else {
- Election election = (Election) entry.getValue();
- switch (election.disqualify(containerID)) {
- case Election.WON:
- processVictory(electionID);
- case Election.LOST:
- i.remove();
- break;
- }
- }
- }
- }
- }
-
- private void processVictory(ID electionID) {
- try {
- config.getContext().sendMessage(null, new Elected(electionID));
- agent.doBootstrap(electionID);
- } catch (IOException e) {
- handleError(e);
- }
- }
-
- private void handleError(Throwable t) {
- t.printStackTrace();
- }
-
- /* (non-Javadoc)
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#dispose(org.eclipse.ecf.core.identity.ID)
- */
- public void dispose(ID containerID) {
- config = null;
- }
+ private final Random random = new Random();
+
+ private Agent agent;
+
+ private ISharedObjectConfig config;
+
+ private final HashMap elections = new HashMap();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#setAgent(org.eclipse.ecf.internal.datashare.Agent)
+ */
+ public void setAgent(Agent agent) {
+ this.agent = agent;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#init(org.eclipse.ecf.core.ISharedObjectConfig)
+ */
+ public void init(ISharedObjectConfig config)
+ throws SharedObjectInitException {
+ this.config = config;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#handleEvent(org.eclipse.ecf.core.util.Event)
+ */
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectContainerJoinedEvent) {
+ ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
+ if (!e.getJoinedContainerID().equals(e.getLocalContainerID()))
+ handleJoined(e.getJoinedContainerID());
+ } else if (event instanceof ISharedObjectContainerDepartedEvent) {
+ ISharedObjectContainerDepartedEvent e = (ISharedObjectContainerDepartedEvent) event;
+ if (!e.getDepartedContainerID().equals(e.getLocalContainerID()))
+ handleDeparted(e.getDepartedContainerID());
+ } else if (event instanceof ISharedObjectMessageEvent) {
+ ISharedObjectMessageEvent e = (ISharedObjectMessageEvent) event;
+ if (e.getData() instanceof Vote)
+ handleVote((Vote) e.getData(), e.getRemoteContainerID());
+ else if (e.getData() instanceof Elected)
+ handleElected((Elected) e.getData());
+ }
+ }
+
+ private void handleJoined(ID containerID) {
+ List members = Arrays.asList(config.getContext().getGroupMemberIDs());
+ members.remove(containerID);
+ members.remove(config.getContext().getLocalContainerID());
+ if (members.isEmpty())
+ processVictory(containerID);
+ else {
+ long ticket = random.nextLong(); // TODO strategize this
+ Election election = new Election(ticket, members);
+ synchronized (elections) {
+ elections.put(containerID, election);
+ }
+
+ try {
+ config.getContext().sendMessage(null,
+ new Vote(ticket, containerID));
+ } catch (IOException e) {
+ handleError(e);
+ }
+ }
+ }
+
+ private void handleVote(Vote msg, ID containerID) {
+ synchronized (elections) {
+ Election election = (Election) elections.get(msg.getElectionID());
+ if (election != null) {
+ switch (election.processVote(msg.getTicket(), containerID)) {
+ case Election.WON:
+ processVictory(msg.getElectionID());
+ case Election.LOST:
+ elections.remove(msg.getElectionID());
+ }
+ }
+ }
+ }
+
+ private void handleElected(Elected msg) {
+ synchronized (elections) {
+ elections.remove(msg.getElectionID());
+ }
+ }
+
+ private void handleDeparted(ID containerID) {
+ synchronized (elections) {
+ for (Iterator i = elections.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ ID electionID = (ID) entry.getKey();
+ if (containerID.equals(electionID))
+ i.remove();
+ else {
+ Election election = (Election) entry.getValue();
+ switch (election.disqualify(containerID)) {
+ case Election.WON:
+ processVictory(electionID);
+ case Election.LOST:
+ i.remove();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private void processVictory(ID electionID) {
+ try {
+ config.getContext().sendMessage(null, new Elected(electionID));
+ agent.doBootstrap(electionID);
+ } catch (IOException e) {
+ handleError(e);
+ }
+ }
+
+ private void handleError(Throwable t) {
+ t.printStackTrace();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#dispose(org.eclipse.ecf.core.identity.ID)
+ */
+ public void dispose(ID containerID) {
+ config = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#createMemento()
+ */
+ public IBootstrapMemento createMemento() {
+ return new BootstrapMemento();
+ }
+
+ public static class BootstrapMemento implements IBootstrapMemento {
+
+ private static final long serialVersionUID = 3256438127341418808L;
+
+ public IBootstrap createBootstrap() {
+ return new LazyElectionBootstrap();
+ }
+ }
}
diff --git a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/ServerBootstrap.java b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/ServerBootstrap.java
index 5dca4a0ca..0d4c7fcaf 100644
--- a/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/ServerBootstrap.java
+++ b/framework/bundles/org.eclipse.ecf.datashare/src/org/eclipse/ecf/internal/datashare/ServerBootstrap.java
@@ -21,49 +21,75 @@ import org.eclipse.ecf.core.util.Event;
*/
public class ServerBootstrap implements IBootstrap {
- private Agent agent;
+ private Agent agent;
- private ISharedObjectConfig config;
+ private ISharedObjectConfig config;
- /* (non-Javadoc)
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#setAgent(org.eclipse.ecf.internal.datashare.Agent)
- */
- public void setAgent(Agent agent) {
- this.agent = agent;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#setAgent(org.eclipse.ecf.internal.datashare.Agent)
+ */
+ public void setAgent(Agent agent) {
+ this.agent = agent;
+ }
- /* (non-Javadoc)
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#init(org.eclipse.ecf.core.ISharedObjectConfig)
- */
- public void init(ISharedObjectConfig config)
- throws SharedObjectInitException {
- this.config = config;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#init(org.eclipse.ecf.core.ISharedObjectConfig)
+ */
+ public void init(ISharedObjectConfig config)
+ throws SharedObjectInitException {
+ this.config = config;
+ }
- /* (non-Javadoc)
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#handleEvent(org.eclipse.ecf.core.util.Event)
- */
- public void handleEvent(Event event) {
- if (event instanceof ISharedObjectContainerJoinedEvent) {
- ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
- if (!e.getJoinedContainerID().equals(e.getLocalContainerID()))
- handleJoined(e.getJoinedContainerID());
- }
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#handleEvent(org.eclipse.ecf.core.util.Event)
+ */
+ public void handleEvent(Event event) {
+ if (event instanceof ISharedObjectContainerJoinedEvent) {
+ ISharedObjectContainerJoinedEvent e = (ISharedObjectContainerJoinedEvent) event;
+ if (!e.getJoinedContainerID().equals(e.getLocalContainerID()))
+ handleJoined(e.getJoinedContainerID());
+ }
+ }
- private void handleJoined(ID containerID) {
- if (config.getContext().isGroupServer()) // TODO how about isGroupManager()?
- agent.doBootstrap(containerID);
- }
+ private void handleJoined(ID containerID) {
+ if (config.getContext().isGroupServer()) // TODO how about isGroupManager()?
+ agent.doBootstrap(containerID);
+ }
- private void handleError(Throwable t) {
- t.printStackTrace();
- }
+ private void handleError(Throwable t) {
+ t.printStackTrace();
+ }
- /* (non-Javadoc)
- * @see org.eclipse.ecf.internal.datashare.IBootstrap#dispose(org.eclipse.ecf.core.identity.ID)
- */
- public void dispose(ID containerID) {
- config = null;
- }
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#dispose(org.eclipse.ecf.core.identity.ID)
+ */
+ public void dispose(ID containerID) {
+ config = null;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ecf.internal.datashare.IBootstrap#createMemento()
+ */
+ public IBootstrapMemento createMemento() {
+ return new BootstrapMemento();
+ }
+
+ public static class BootstrapMemento implements IBootstrapMemento {
+
+ private static final long serialVersionUID = 3691040980384299317L;
+
+ public IBootstrap createBootstrap() {
+ return new ServerBootstrap();
+ }
+ }
}

Back to the top