📄 primeclient.java
字号:
package primecruncher;import net.jxta.document.StructuredTextDocument;import javax.swing.*;import java.awt.*;import java.awt.event.WindowEvent;import java.awt.event.WindowAdapter;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.Map;import java.util.StringTokenizer;/** * A program that computes a list of prime numbers between two integers in a * distributed manner. It asynchronously discovers peers that advertise a * prime number searching service via a <code>ModuleSpecAdvertisement</code>. * When a user enters two integers, this program divides that list between all the * peers known to offer the prime searching functionality at the time. It then * opens a pipe to each such peer, and sends a message to each containing that peer's * segment boundary integers. That message also contains a <code>PipeAdvertisement</code> * to allow the prime seaching peer to send its response back to the requesting peer. <p> * * A prime searching peer computes the list of primes * between those boundary numbers, opens a pipe back to the requesting peer, and sends * a response message back, containing the computed list (as a comma-separated integer list). * The client peer waits for all peers to send back their responses, and it then * assembles the complete primes list from the partial results, and displays that list * back to the user.<p> * * This peer manages a cache of all known prime searching peers on the network. That list * is saved persistently.<p> * * For each * peer it finds, it periodically collects statistics about that peer. Statistics include the * peer's uptime, the number of message that peer processed, etc. It then scores each prime * searching peer according to those statistics. When a user submits a new search request, * the program favors peers with the best overall scores. When a request is distributed, this * peer will parcel out the complete list not equally, but according to the scores of the * intended target peers: Peers that perform better will receive a longer list, whereas * peers performing poorly will receive a shorter one.<p> * When a message is sent to a peer, this peer notes the message that was sent, and the peer * to which the message was directed. When a response for a message is received, this peer * notes the time it took for the response to get back; it then takes that round-trip time, * plus the size of the list comprising that request to estimate the prime searching peer's * performance. That performance metrics is then taken into account at subsequent user * requests.<p> * When a new requests is parcelled out, all known peers are utilized, regardless of their * performance metrics, if possible, to take advantage of parallelism.<p> * When a message is sent out, there is no guarantee that an answer will be received. A time * boundary is set for how long to wait for a response. If a response is not received within * that boundary, the request will be discarded, and a new request for that list portion is * submitted to another peer. (HOW TO COMPUTE BOUNDARY?)<p> * The <code>ResultListener</code> interface specifies a listener for prime results. * That listener is invoked when the results for a requested computation completes. */public class PrimeClient extends JPanel implements ResultListener { //This object does the dispatching to other peers //It acts as a proxy for the prime cruching service private Dispatcher primeservice = null; private JTextArea results; private JTextArea status; /** * A graphical client for the prime-search service */ public PrimeClient(Dispatcher disp) { primeservice = disp; buildGUI(); } private void buildGUI() { setLayout(new BorderLayout()); //top panel JPanel topPanel = new JPanel(); topPanel.setLayout(new FlowLayout()); final JTextField fromField = new JTextField(10); final JTextField toField = new JTextField(10); topPanel.add(new JLabel("From: ")); topPanel.add(fromField); topPanel.add(new JLabel("To: ")); topPanel.add(toField); status = new JTextArea(5, 20); results = new JTextArea(20, 20); JScrollPane scrollPane = new JScrollPane(results); JScrollPane statusScroll = new JScrollPane(status); JPanel centerPanel = new JPanel(); centerPanel.setLayout(new BorderLayout()); centerPanel.add(statusScroll, BorderLayout.NORTH); centerPanel.add(scrollPane, BorderLayout.CENTER); JButton goButton = new JButton("Go"); JButton exitButton = new JButton("Exit"); JPanel buttPanel = new JPanel(); buttPanel.add(goButton); buttPanel.add(exitButton); add(topPanel, BorderLayout.NORTH); add(centerPanel, BorderLayout.CENTER); add(buttPanel, BorderLayout.SOUTH); goButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { String low = fromField.getText(); String high = toField.getText(); results.setText(""); try { int l = Integer.parseInt(low); int h = Integer.parseInt(high); primeservice.processPrimes(l, h, PrimeClient.this); } catch (NumberFormatException e1) { status.setText("Wrong args"); } } }); exitButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); } private void displayStats(ComputeStats stats) { //status.append("Stats for job " + stats.getJobID()); ComputeStats.NodeStat[] ns = stats.getNodeStats(); for (int i=0; i < ns.length; i++) { status.append(ns[i].getNodeID() + " computed segment "); status.append(new Integer(ns[i].getLow()).toString() + "-"); status.append(new Integer(ns[i].getHi()).toString() + " in "); status.append(new Double((ns[i].getComputeTime())/1000).toString() + " seconds.\n"); } } private void displayResult(Map res) { String resString = (String)res.get(ServiceConstants.RESULTSTRING); //if there are too many results, don't display if (resString.length() > 100000) return; StringTokenizer tk = new StringTokenizer(resString, ","); int i = 0; while (tk.hasMoreTokens()) { results.append(tk.nextToken() + " "); if (i > 25) { results.append("\n"); i = 0; } i++; } } public static void main(String[] args) { Dispatcher disp = new Dispatcher(); PrimeClient app = new PrimeClient(disp); JFrame f = new JFrame("Prime cruncher"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); Toolkit tk = Toolkit.getDefaultToolkit(); Dimension dim = tk.getScreenSize(); int appWidth = (int)(dim.getWidth()/2); int appHeight = (int)(dim.getHeight()/2); app.setPreferredSize(new Dimension(appWidth, appHeight)); int x = (int)dim.getWidth()/2 - (int)appWidth/2; int y = (int)dim.getHeight()/2 - (int)appHeight/2; f.getContentPane().add(app); f.pack(); f.setLocation(x, y); f.setVisible(true); } public void resultEvent(Map result) { displayStats((ComputeStats)result.get(ServiceConstants.JOBSTATS)); displayResult(result); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -