📄 experserver.java
字号:
nodes[i].node = i; seedSelect.add(nodes[i].rSeed); p.add(nodes[i]); } } /* Handle events from the control panel buttons. */ public void actionPerformed(ActionEvent ae) { // All of these actions are long-running so we launch them in separate threads to avoid tying up the GUI thread // TODO some of these buttons should be disabled while an experiment is running Object src = ae.getSource(); if (src == bScanUsb) { // Re-run the initial scan for USB-serial convertors new Thread(new Runnable() { public void run() { findShells(); } }).start(); } else if (src == bLogFile) { // Toggle whether we are logging if (bLogFile.isSelected() && (logStream == null || !tLogFile.getText().equals(logName))) { try { // If the file name in the text field changed, open a new log file, // otherwise we continue appending to the original log file PrintWriter pw = new PrintWriter(new FileWriter(tLogFile.getText())); setLogStream(pw); } catch (IOException e) { e.printStackTrace(); } } setLogging(bLogFile.isSelected()); } else if (src == bExperAll) { if (seedNode == null) { // Can't run reprogramming without a seed node // TODO We need at least one target, too JOptionPane.showMessageDialog(this, "Please select a seed node", "Run All", JOptionPane.ERROR_MESSAGE); return; } // Launch a thread to run several experiments in a row experThread = new Thread(new Runnable() { public void run() { try { // Run five iterations at image sizes ranging from 2 pages to 10 pages // The text fields give a starting image size and iteration, // this is useful for continuing a series of experiments that was interrupted expers.runMany(seedNode, connections, 2, 10, 2, 5, Integer.parseInt(tStartSize.getText()), Integer.parseInt(tStartIter.getText())); } catch (InterruptedException e) { System.out.println("Experiment interrupted."); } catch (IOException e) { JOptionPane.showMessageDialog(ControlPanel.this, "IOException: "+e, "Run All", JOptionPane.ERROR_MESSAGE); e.printStackTrace(); } } }); experThread.start(); } else if (src == bExperV) { if (seedNode == null) { JOptionPane.showMessageDialog(this, "Please select a seed node", "Experiment 1", JOptionPane.ERROR_MESSAGE); return; } // Launch a new experiment // The update is triggered by incrementing the version number at the seed node experThread = new Thread(new Runnable() { public void run() { try { expers.experiment1(seedNode, connections, false, -1); } catch (InterruptedException e) { System.out.println("Experiment interrupted."); } } }); experThread.start(); } else if (src == bExperS) { if (seedNode == null) { JOptionPane.showMessageDialog(this, "Please select a seed node", "Experiment 1", JOptionPane.ERROR_MESSAGE); return; } // Launch a new experiment and increment the image size // The update is triggered by incrementing the version number at the seed node // TODO experiment1() allows setting an arbitrary page size, add a text field for this experThread = new Thread(new Runnable() { public void run() { try { expers.experiment1(seedNode, connections, true, -1); } catch (InterruptedException e) { System.out.println("Experiment interrupted."); } } }); experThread.start(); } else if (src == bStop) { // The experiment thread will throw InterruptedException from any wait() calls if (experThread != null) experThread.interrupt(); new Thread(new Runnable() { public void run() { System.out.println("Stopping updates on all nodes:"); try { for (Iterator<ShellConnection> i = connections.iterator(); i.hasNext(); ) { ShellConnection sc = i.next(); if (seedNode == sc) continue; int app = 1; if (sc.isTarget) app = 0; System.out.print(" "+(sc.ui==null? "<null>" : Integer.toString(sc.ui.node))); sc.stopUpdating(app); } System.out.println(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(); } }).start(); } else if (src == bPoll) { // If we missed the initial ping reply when we started any new connections, ping them again // TODO Why does this happen new Thread(new Runnable() { public void run() { for (int i = connections.size()-1; i>=0; --i) { ShellConnection sc = connections.get(i); if (sc.ui == null) { sc.sendNodeCommand(AQSHELL_GETVERSION); } } } }).start(); } else if (src == bPollAll) { // Ping all connections // TODO Do something to all the node GUI's to help us see the ping, for example disconnect all of them new Thread(new Runnable() { public void run() { for (int i = connections.size()-1; i>=0; --i) { ShellConnection sc = connections.get(i); sc.sendNodeCommand(AQSHELL_GETVERSION); } } }).start(); } } } /* This class is one element of the grid of nodes shown by the control panel. */ class NodeSquare extends JPanel implements ActionListener { private static final long serialVersionUID = 3834587720948199730L; // Eclipse told me to put this in JLabel lConn; JLabel lFinish; JLabel lMsg; JButton bStats; JButton bStart; JButton bStop; JButton bClear; JButton bGetStats; JButton bVersion; JTextField tVersion; JButton bSize; JTextField tSize; JButton bCache; JTextField tCache; JTextField tCacheApp; JCheckBox cTarget; JRadioButton rSeed; JLabel lVerPage; JButton bStopUpdate; JTextField tStopApp; // This node's index that points back into the array // ShellConnection checks this whenever it gets a packet from a node int node; // Points back to the connection for this node, may be null ShellConnection connection; NodeSquare() { setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); lConn = new JLabel("Not Connected"); add(lConn); lFinish = new JLabel("Not Finished"); add(lFinish); lVerPage = new JLabel("( , )"); add(lVerPage); lMsg = new JLabel("No Messages"); add(lMsg); /*bStats = new JButton("Stats"); bStats.addActionListener(this); add(bStats);*/ bStart = new JButton("Start Record"); bStart.addActionListener(this); add(bStart); bStop = new JButton("End Record"); bStop.addActionListener(this); add(bStop); bClear = new JButton("Clear Stats"); bClear.addActionListener(this); add(bClear); bGetStats = new JButton("Get Stats"); bGetStats.addActionListener(this); add(bGetStats); JPanel p = new JPanel(); bStopUpdate = new JButton("Stop Update"); bStopUpdate.addActionListener(this); p.add(bStopUpdate); tStopApp = new JTextField(3); p.add(tStopApp); add(p); p = new JPanel(); bVersion = new JButton("Set Version"); bVersion.addActionListener(this); p.add(bVersion); tVersion = new JTextField(3); p.add(tVersion); add(p); p = new JPanel(); bSize = new JButton("Set Version and Size"); bSize.addActionListener(this); p.add(bSize); tSize = new JTextField(3); p.add(tSize); add(p); p = new JPanel(); bCache = new JButton("Set Cache Size"); bCache.addActionListener(this); p.add(bCache); tCache = new JTextField(3); p.add(tCache); tCacheApp = new JTextField(3); p.add(tCacheApp); add(p); p = new JPanel(); cTarget = new JCheckBox("Target"); cTarget.addActionListener(this); p.add(cTarget); rSeed = new JRadioButton("Seed"); rSeed.addActionListener(this); p.add(rSeed); add(p); connection = null; checkEnable(); } // Disable all the controls if there is no node connected void checkEnable() { bVersion.setEnabled(connection != null); bSize.setEnabled(connection != null); bCache.setEnabled(connection != null); cTarget.setEnabled(connection != null); rSeed.setEnabled(connection != null); bStopUpdate.setEnabled(connection != null); } // Update the label that shows the version a number of available pages public void showVersionPage(int b, int c) { lVerPage.setText("("+(b&0xFF)+", "+(c&0xFF)+")"); } // Connect a node to this GUI (or disconnect it) public void setConnection(ShellConnection connection) { this.connection = connection; lConn.setText(connection != null? "CONNECTED" : "Not Connected"); checkEnable(); } // Set the label that says this node has finished updating public void setFinished(boolean state) { lFinish.setText(state? "FINISHED" : "Not Finished"); } // Display a message for this node // TODO More commands should make use of this public void setMessage(String msg) { lMsg.setText(msg); } public void actionPerformed(ActionEvent ae) { Object src = ae.getSource(); /*if (src == bStats) { connection.printStats(); } else*/ if (src == bVersion) { // Change the version number of the home application on a node connection.setVersion(/*Integer.parseInt(tVerApp.getText()),*/ Integer.parseInt(tVersion.getText())); } else if (src == bSize) { // Change the size of the home application on a node // This also uses the version field, since it is a bad thing to set the size without changing the version, too // If you change the size without changing the version, updates may flow in unwanted directions and the image // will fail its CRC, since no profile packet will be flooded with the new image CRC connection.setImageSize(Integer.parseInt(tSize.getText()), Integer.parseInt(tVersion.getText())); } else if (src == bCache) { // Change the cache size on a forwarding node // You have to specify the application index connection.setCacheSize(Integer.parseInt(tCache.getText()), Integer.parseInt(tCacheApp.getText())); } else if (src == cTarget) { // Set this node as a target, experiments will wait for it to finish connection.isTarget = cTarget.isSelected(); // TODO these checkboxes don't enable and disable quite correctly rSeed.setEnabled(cTarget.isSelected()); } else if (src == rSeed) { // Set this node as the seed node // We use a checkbox group so only one may be selected if (rSeed.isSelected()) seedNode = connection; // TODO these checkboxes don't enable and disable quite correctly cTarget.setEnabled(rSeed.isSelected()); } else if (src == bStart) { connection.sendShellCommand(AQSHELL_STARTSTATS); } else if (src == bStop) { connection.sendShellCommand(AQSHELL_STOPSTATS); } else if (src == bClear) { connection.sendShellCommand(AQSHELL_CLEARSTATS); } else if (src == bGetStats) { connection.sendShellCommand(AQSHELL_GETSTATS); } else if (src == bStopUpdate) { new Thread(new Runnable() { public void run() { try { connection.stopUpdating(Integer.parseInt(tStopApp.getText())); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } } } /* This class collects methods for running experiments on the testbed. */ class Experiment { /* Send the command to all the aqshells in collection 'all', then wait for each to acknowledge. * Resend the command every 5 seconds. * If 'print' is true, print the node IDs as the commands are ACKed. * This method may be interrupted. */ void sendToAllShells(Collection<ShellConnection> all, byte command, boolean print) throws InterruptedException { for (Iterator<ShellConnection> i = all.iterator(); i.hasNext(); ) { ShellConnection sc = i.next(); if (print) System.out.print(" "+(sc.ui==null? "<null>" : Integer.toString(sc.ui.node))); synchronized (sc) { sc.setAck(-1); while (sc.getAck() != command) { sc.sendShellCommand(command); sc.wait(5000); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -