/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.
*/ package org.apache.catalina.tribes.demos;
/** * Example of how the lazy replicated map works, also shows how the BackupManager works in a Tomcat cluster.
*/ publicclass MapDemo implements ChannelListener, MembershipListener {
/** * The Map containing the replicated data
*/ protected LazyReplicatedMap<String, StringBuilder> map;
/** * Table to be displayed in Swing
*/ protected SimpleTableDemo table;
/** * Constructs a map demo object. * * @param channel - the Tribes channel object to be used for communication * @param mapName - the name of this map
*/ public MapDemo(Channel channel, String mapName) { // instantiate the replicated map
map = new LazyReplicatedMap<>(null, channel, 5000, mapName, null); // create a gui, name it with the member name of this JVM
table = SimpleTableDemo.createAndShowGUI(map, channel.getLocalMember(false).getName()); // add ourself as a listener for messages
channel.addChannelListener(this); // add ourself as a listener for memberships
channel.addMembershipListener(this); // initialize the map by receiving a fake message this.messageReceived(null, null);
}
/** * Decides if the messageReceived should be invoked will always return false since we rely on the lazy map to do all * the messaging for us
*/
@Override publicboolean accept(Serializable msg, Member source) { // simple refresh the table model
table.dataModel.getValueAt(-1, -1); returnfalse;
}
/** * Invoked if accept returns true. No op for now * * @param msg - the message received * @param source - the sending member
*/
@Override publicvoid messageReceived(Serializable msg, Member source) { // NOOP
}
/** * Invoked when a member is added to the group
*/
@Override publicvoid memberAdded(Member member) { // NOOP
}
/** * Invoked when a member leaves the group
*/
@Override publicvoid memberDisappeared(Member member) { // just refresh the table model
table.dataModel.getValueAt(-1, -1);
}
@SuppressWarnings("unused") publicstaticvoid main(String[] args) throws Exception { long start = System.currentTimeMillis(); // create a channel object
ManagedChannel channel = (ManagedChannel) ChannelCreator.createChannel(args); // define a map name, unless one is defined as a parameters
String mapName = "MapDemo"; if (args.length > 0 && (!args[args.length - 1].startsWith("-"))) {
mapName = args[args.length - 1];
} // start the channel
channel.start(Channel.DEFAULT); // listen for shutdown
Runtime.getRuntime().addShutdownHook(new Shutdown(channel)); // create a map demo object new MapDemo(channel, mapName);
// put the main thread to sleep until we are done
System.out.println("System test complete, time to start=" + (System.currentTimeMillis() - start) + " ms. Sleeping to let threads finish."); Thread.sleep(60 * 1000 * 60);
}
/** * Listens for shutdown events, and stops this instance
*/ publicstaticclass Shutdown extendsThread { // the channel running in this demo
ManagedChannel channel = null;
public Shutdown(ManagedChannel channel) { this.channel = channel;
}
@Override publicvoid run() {
System.out.println("Shutting down..."); // create an exit thread that forces a shutdown if the JVM won't exit cleanly
SystemExit exit = new SystemExit(5000);
exit.setDaemon(true);
exit.start(); try { // stop the channel
channel.stop(Channel.DEFAULT);
} catch (Exception x) {
x.printStackTrace();
}
System.out.println("Channel stopped.");
}
}
JTextField txtAddKey = new JTextField(20);
JTextField txtAddValue = new JTextField(20);
JTextField txtRemoveKey = new JTextField(20);
JTextField txtChangeKey = new JTextField(20);
JTextField txtChangeValue = new JTextField(20);
JTable table = null;
public SimpleTableDemo(LazyReplicatedMap<String, StringBuilder> map) { super(); this.map = map;
public JButton createButton(String text, String command) {
JButton button = new JButton(text);
button.setActionCommand(command);
button.addActionListener(this); return button;
}
@Override publicvoid actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand()); if ("add".equals(e.getActionCommand())) {
System.out.println("Add key:" + txtAddKey.getText() + " value:" + txtAddValue.getText());
map.put(txtAddKey.getText(), new StringBuilder(txtAddValue.getText()));
} if ("change".equals(e.getActionCommand())) {
System.out.println("Change key:" + txtChangeKey.getText() + " value:" + txtChangeValue.getText());
StringBuilder buf = map.get(txtChangeKey.getText()); if (buf != null) {
buf.delete(0, buf.length());
buf.append(txtChangeValue.getText());
map.replicate(txtChangeKey.getText(), true);
} else {
buf = new StringBuilder();
buf.append(txtChangeValue.getText());
map.put(txtChangeKey.getText(), buf);
}
} if ("remove".equals(e.getActionCommand())) {
System.out.println("Remove key:" + txtRemoveKey.getText());
map.remove(txtRemoveKey.getText());
} if ("sync".equals(e.getActionCommand())) {
System.out.println("Syncing from another node.");
map.transferState();
} if ("random".equals(e.getActionCommand())) { Thread t = newThread() {
@Override publicvoid run() { for (int i = 0; i < 5; i++) {
String key = random(5, 0, 0, true, true, null);
map.put(key, new StringBuilder(key));
dataModel.fireTableDataChanged();
table.paint(table.getGraphics()); try {
sleep(500);
} catch (InterruptedException x) {
interrupted();
}
}
}
};
t.start();
}
if ("replicate".equals(e.getActionCommand())) {
System.out.println("Replicating out to the other nodes.");
map.replicate(true);
}
dataModel.getValueAt(-1, -1);
}
publicstaticfinal Random random = new Random();
publicstatic String random(int count, int start, int end, boolean letters, boolean numbers, char[] chars) { if (count == 0) { return"";
} elseif (count < 0) { thrownew IllegalArgumentException("Requested random string length " + count + " is less than 0.");
} if ((start == 0) && (end == 0)) {
end = 'z' + 1;
start = ' '; if (!letters && !numbers) {
start = 0;
end = Integer.MAX_VALUE;
}
}
char[] buffer = newchar[count]; int gap = end - start;
while (count-- != 0) { char ch; if (chars == null) {
ch = (char) (random.nextInt(gap) + start);
} else {
ch = chars[random.nextInt(gap) + start];
} if ((letters && Character.isLetter(ch)) || (numbers && Character.isDigit(ch)) ||
(!letters && !numbers)) { if (ch >= 56320 && ch <= 57343) { if (count == 0) {
count++;
} else { // low surrogate, insert high surrogate after putting it in
buffer[count] = ch;
count--;
buffer[count] = (char) (55296 + random.nextInt(128));
}
} elseif (ch >= 55296 && ch <= 56191) { if (count == 0) {
count++;
} else { // high surrogate, insert low surrogate before putting it in
buffer[count] = (char) (56320 + random.nextInt(128));
count--;
buffer[count] = ch;
}
} elseif (ch >= 56192 && ch <= 56319) { // private high surrogate, no effing clue, so skip it
count++;
} else {
buffer[count] = ch;
}
} else {
count++;
}
} returnnew String(buffer);
}
privatevoid printDebugData(JTable table) { int numRows = table.getRowCount(); int numCols = table.getColumnCount();
javax.swing.table.TableModel model = table.getModel();
System.out.println("Value of data: "); for (int i = 0; i < numRows; i++) {
System.out.print(" row " + i + ":"); for (int j = 0; j < numCols; j++) {
System.out.print(" " + model.getValueAt(i, j));
}
System.out.println();
}
System.out.println("--------------------------");
}
/* * Create the GUI and show it. For thread safety, this method should be invoked from the event-dispatching * thread.
*/ publicstatic SimpleTableDemo createAndShowGUI(LazyReplicatedMap<String, StringBuilder> map, String title) { // Make sure we have nice window decorations.
JFrame.setDefaultLookAndFeelDecorated(true);
// Create and set up the window.
JFrame frame = new JFrame("SimpleTableDemo - " + title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create and set up the content pane.
SimpleTableDemo newContentPane = new SimpleTableDemo(map);
newContentPane.setOpaque(true); // content panes must be opaque
frame.setContentPane(newContentPane);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.