diff options
| author | pnehrer | 2005-05-02 04:18:27 +0000 |
|---|---|---|
| committer | pnehrer | 2005-05-02 04:18:27 +0000 |
| commit | 93a39c2983ae889ee07a62fb9a3868733ec55ecb (patch) | |
| tree | ccb33f090c935fd20a4a879a6303d1fbdf818100 | |
| parent | 03f151c14b1923630d386dc2e2e26d009d19dbc2 (diff) | |
| download | org.eclipse.ecf-93a39c2983ae889ee07a62fb9a3868733ec55ecb.tar.gz org.eclipse.ecf-93a39c2983ae889ee07a62fb9a3868733ec55ecb.tar.xz org.eclipse.ecf-93a39c2983ae889ee07a62fb9a3868733ec55ecb.zip | |
Checkpoint.
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(); + } + } } |
