Search in sources :

Example 1 with Host

use of gov.sandia.n2a.host.Host in project n2a by frothga.

the class PanelRun method delete.

public void delete(TreePath[] paths) {
    if (paths.length == 0)
        return;
    // The node that will be focused after all the deletes are done.
    NodeBase nextSelection = null;
    TreePath leadSelection = tree.getLeadSelectionPath();
    if (leadSelection != null)
        nextSelection = (NodeBase) leadSelection.getLastPathComponent();
    int firstRow = Integer.MAX_VALUE;
    int lastRow = 0;
    for (int i = 0; i < paths.length; i++) {
        TreePath path = paths[i];
        // Ensure that we don't try to delete something twice.
        NodeBase node = (NodeBase) path.getLastPathComponent();
        if (node.markDelete) {
            paths[i] = null;
            continue;
        }
        node.markDelete = true;
        // Current focus is a node that will be deleted. This is almost always the case, except when jobs are deleted by the Studies panel.
        if (nextSelection == node)
            nextSelection = null;
        // In some cases (such as ctrl-click), the rows may not be in ascending order.
        int row = tree.getRowForPath(path);
        firstRow = Math.min(firstRow, row);
        lastRow = Math.max(lastRow, row);
    }
    // No rows passed the filter above (because they were already selected).
    if (firstRow == Integer.MAX_VALUE)
        return;
    NodeBase firstSelection = (NodeBase) tree.getPathForRow(firstRow).getLastPathComponent();
    NodeBase lastSelection = (NodeBase) tree.getPathForRow(lastRow).getLastPathComponent();
    if (nextSelection == null)
        nextSelection = (NodeBase) lastSelection.getNextSibling();
    if (nextSelection != null) {
        // Could be root. Root is never selected, so the following test works correctly in that case.
        NodeBase parent = (NodeBase) nextSelection.getParent();
        if (// next sibling will also die, so need next sibling of parent.
        tree.isPathSelected(new TreePath(parent.getPath()))) {
            nextSelection = (NodeBase) parent.getNextSibling();
        }
    }
    // If this exists, then it is guaranteed to continue to exist after deletion.
    if (nextSelection == null)
        nextSelection = (NodeBase) firstSelection.getPreviousSibling();
    // "firstSelection" could be first file under a job, or first job in tree. In the latter case, the tree will be empty after delete.
    if (nextSelection == null)
        nextSelection = (NodeBase) firstSelection.getParent();
    if (// Tree will be empty after delete.
    nextSelection == root) {
        // Shut down the display thread.
        synchronized (displayText) {
            if (displayThread != null) {
                displayThread.stop = true;
                displayThread = null;
            }
            // All access to this happens on EDT, so safe.
            displayNode = null;
            displayText.setText("");
        }
        displayChart.buttonBar.setVisible(false);
        if (displayPane.getViewport().getView() != displayText)
            displayPane.setViewportView(displayText);
    } else // Set the new selection. This will not be touched by the delete process.
    {
        TreePath path = new TreePath(nextSelection.getPath());
        tree.setSelectionPath(path);
        tree.scrollPathToVisible(path);
    }
    // Ensure that strikethru marks will be displayed to user.
    tree.repaint();
    // Spawn the rest of the delete process off to a separate thread.
    // The tree will be updated on the EDT as work progresses.
    Thread deleteThread = new Thread("Delete Jobs") {

        public void run() {
            Map<Host, HostDeleteThread> hostThreads = new HashMap<Host, HostDeleteThread>();
            Set<NodeJob> parents = new HashSet<NodeJob>();
            for (TreePath path : paths) {
                if (path == null)
                    continue;
                final NodeBase node = (NodeBase) path.getLastPathComponent();
                if (node instanceof NodeJob) {
                    NodeJob job = (NodeJob) node;
                    parents.add(job);
                    synchronized (job) {
                        if (job.complete < 1 || job.complete == 3) {
                            // It's important that the job not have resources locked in the directory when we try to delete it.
                            // If the job is still running, downgrade the delete request to a kill request.
                            // The user will have to hit delete again, once the job dies.
                            job.stop();
                            job.markDelete = false;
                            EventQueue.invokeLater(new Runnable() {

                                public void run() {
                                    tree.repaint(tree.getPathBounds(new TreePath(job.getPath())));
                                }
                            });
                            continue;
                        }
                    }
                } else {
                    if (parents.contains((NodeJob) node.getParent()))
                        continue;
                }
                NodeJob job;
                if (node instanceof NodeJob) {
                    job = (NodeJob) node;
                    // Signal the monitor thread to drop this job.
                    synchronized (job) {
                        job.deleted = true;
                    }
                    synchronized (jobNodes) {
                        jobNodes.remove(job.key);
                    }
                } else {
                    job = (NodeJob) node.getParent();
                }
                Host env = Host.get(job.getSource());
                HostDeleteThread t = hostThreads.get(env);
                if (t == null) {
                    t = new HostDeleteThread(env);
                    t.setDaemon(true);
                    t.start();
                    hostThreads.put(env, t);
                }
                synchronized (t.nodes) {
                    t.nodes.add(node);
                }
            }
            for (HostDeleteThread t : hostThreads.values()) t.allQueued = true;
        }
    };
    // It's OK if this work is interrupted. Any undeleted item will simply show up in the tree on next launch, and the user can try again.
    deleteThread.setDaemon(true);
    deleteThread.start();
}
Also used : TreePath(javax.swing.tree.TreePath) HashMap(java.util.HashMap) Host(gov.sandia.n2a.host.Host) Point(java.awt.Point) HashSet(java.util.HashSet)

Example 2 with Host

use of gov.sandia.n2a.host.Host in project n2a by frothga.

the class NodeJob method reset.

/**
 *        Remove all files from the job dir except the main job file.
 *        This allows the job to restart cleanly, without file-creation conflicts.
 */
public synchronized void reset() {
    // Reset variables to initial state.
    complete = -1;
    dateStarted = null;
    dateFinished = null;
    expectedSimTime = 0;
    lastMonitored = 0;
    lastActive = 0;
    lastDisplay = 0;
    // Purge files
    Host localhost = Host.get();
    MNode source = getSource();
    Path localJobDir = Host.getJobDir(Host.getLocalResourceDir(), source);
    try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(localJobDir)) {
        for (Path path : dirStream) {
            if (path.endsWith("job"))
                continue;
            // deleteTree() works for both files and dirs, and also absorbs most exceptions.
            localhost.deleteTree(path);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    PanelRun panelRun = PanelRun.instance;
    if (!panelRun.tree.isCollapsed(new TreePath(getPath())))
        build(panelRun.tree);
}
Also used : Path(java.nio.file.Path) TreePath(javax.swing.tree.TreePath) TreePath(javax.swing.tree.TreePath) Host(gov.sandia.n2a.host.Host) IOException(java.io.IOException) MNode(gov.sandia.n2a.db.MNode)

Example 3 with Host

use of gov.sandia.n2a.host.Host in project n2a by frothga.

the class NodeJob method monitorProgress.

public synchronized void monitorProgress() {
    if (deleted)
        return;
    if (complete >= 1 && complete != 3)
        return;
    // Limit monitoring to no more than once per second.
    long elapsed = System.currentTimeMillis() - lastMonitored;
    long wait = 1000 - elapsed;
    if (wait > 0) {
        try {
            Thread.sleep(wait);
        } catch (InterruptedException e) {
        }
    }
    lastMonitored = System.currentTimeMillis();
    float oldComplete = complete;
    MNode source = getSource();
    Host env = Host.get(source);
    Path localJobDir = Host.getJobDir(Host.getLocalResourceDir(), source);
    // If job is remote, attempt to grab its state files.
    // TODO: handle remote jobs waiting in queue. Plan is to update "started" file with queue status.
    Path finished = localJobDir.resolve("finished");
    if (!Files.exists(finished) && env instanceof Remote) {
        @SuppressWarnings("resource") Remote remote = (Remote) env;
        if (remote.isConnected() || remote.isEnabled()) {
            try {
                Path remoteJobDir = Host.getJobDir(env.getResourceDir(), source);
                Path remoteFinished = remoteJobDir.resolve("finished");
                // throws an exception if the remote file does not exist
                Files.copy(remoteFinished, finished);
            } catch (Exception e) {
            }
        }
    }
    if (complete == -1) {
        Path started = localJobDir.resolve("started");
        if (Files.exists(started)) {
            complete = 0;
            dateStarted = new Date(Host.lastModified(started));
            lastActive = dateStarted.getTime();
        }
    }
    Backend simulator = Backend.getBackend(source.get("backend"));
    if (complete >= 0 && complete < 1) {
        float percentDone = 0;
        if (expectedSimTime == 0)
            expectedSimTime = new UnitValue(source.get("duration")).get();
        if (expectedSimTime > 0)
            percentDone = (float) (simulator.currentSimTime(source) / expectedSimTime);
        if (Files.exists(finished)) {
            checkFinished(finished);
        } else {
            try {
                long currentTime = System.currentTimeMillis();
                if (simulator.isActive(source)) {
                    lastActive = currentTime;
                } else if (currentTime - lastActive > activeTimeout) {
                    if (percentDone < 1) {
                        // Give it up for dead.
                        Files.copy(new ByteArrayInputStream("dead".getBytes("UTF-8")), finished);
                        complete = 4;
                    } else // Job appears to be actually finished, even though "finished" hasn't been written yet.
                    {
                        // Fake the "finished" file. This might be overwritten later by the batch process.
                        // Most likely, it will also report that we succeeded, so presume that things are fine.
                        Files.copy(new ByteArrayInputStream("success".getBytes("UTF-8")), finished);
                        complete = 1;
                    }
                }
            } catch (Exception e) {
            }
        }
        if (complete >= 0 && complete < 1)
            complete = Math.min(0.99999f, percentDone);
    }
    if (complete == 3) {
        // Check if process is still lingering
        if (!simulator.isActive(source))
            complete = 4;
    }
    PanelRun panelRun = PanelRun.instance;
    PanelStudy panelStudy = PanelStudy.instance;
    // Probably running headless, so skip all UI updates.
    if (panelRun == null)
        return;
    if (complete != oldComplete) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                panelRun.model.nodeChanged(NodeJob.this);
                if (panelRun.displayNode == NodeJob.this) {
                    panelRun.buttonStop.setEnabled(complete < 1 || complete == 3);
                    panelRun.viewJob(true);
                } else if (panelRun.displayNode instanceof NodeFile && panelRun.displayNode.getParent() == NodeJob.this) {
                    panelRun.buttonStop.setEnabled(complete < 1 || complete == 3);
                    // Update the display every 5 seconds during the run.
                    // Some displays, such as a chart, could take longer than 5s to construct, so don't interrupt those.
                    // Always update the display when a run finishes.
                    long currentTime = System.currentTimeMillis();
                    if (complete >= 1 && complete != 3 || panelRun.displayThread == null && currentTime - lastDisplay > 5000) {
                        lastDisplay = currentTime;
                        panelRun.viewFile(true);
                    }
                }
                // panelStudy could be null for a brief moment during startup
                if (panelStudy != null)
                    panelStudy.tableSamples.updateJob(key);
            }
        });
    }
    if (!panelRun.tree.isCollapsed(new TreePath(getPath())))
        build(panelRun.tree);
}
Also used : Path(java.nio.file.Path) TreePath(javax.swing.tree.TreePath) Remote(gov.sandia.n2a.host.Remote) UnitValue(gov.sandia.n2a.language.UnitValue) Host(gov.sandia.n2a.host.Host) MNode(gov.sandia.n2a.db.MNode) IOException(java.io.IOException) Date(java.util.Date) PanelStudy(gov.sandia.n2a.ui.studies.PanelStudy) Backend(gov.sandia.n2a.plugins.extpoints.Backend) TreePath(javax.swing.tree.TreePath) ByteArrayInputStream(java.io.ByteArrayInputStream)

Example 4 with Host

use of gov.sandia.n2a.host.Host in project n2a by frothga.

the class SettingsBackend method getPanel.

@SuppressWarnings("serial")
@Override
public Component getPanel() {
    if (scrollPane != null)
        return scrollPane;
    JPanel view = new JPanel();
    scrollPane = new JScrollPane(view);
    for (Host h : Host.getHosts()) model.addElement(h);
    list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    list.addListSelectionListener(new ListSelectionListener() {

        public void valueChanged(ListSelectionEvent e) {
            if (e.getValueIsAdjusting())
                return;
            Host h = (Host) list.getSelectedValue();
            if (h == null)
                return;
            bind(h.config.childOrCreate("backend", key));
        }
    });
    list.setCellRenderer(new DefaultListCellRenderer() {

        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            Host h = (Host) value;
            String name = h.name;
            if (h.config.get("backend", key).equals("0"))
                name = "<html><s>" + name + "</s></html>";
            return super.getListCellRendererComponent(list, name, index, isSelected, cellHasFocus);
        }
    });
    InputMap inputMap = list.getInputMap();
    inputMap.put(KeyStroke.getKeyStroke("DELETE"), "toggleEnable");
    inputMap.put(KeyStroke.getKeyStroke("BACK_SPACE"), "toggleEnable");
    inputMap.put(KeyStroke.getKeyStroke("SPACE"), "toggleEnable");
    ActionMap actionMap = list.getActionMap();
    actionMap.put("toggleEnable", new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            Host h = (Host) list.getSelectedValue();
            if (h == null)
                return;
            boolean disabled = h.config.get("backend", key).equals("0");
            if (disabled)
                h.config.set(null, "backend", key);
            else
                h.config.set("0", "backend", key);
            list.repaint();
        }
    });
    JPanel panelList = Lay.BL("C", list, "pref=[100,200]");
    panelList.setBorder(LineBorder.createBlackLineBorder());
    panelList = (JPanel) Lay.eb(Lay.BL("C", panelList), "5");
    editor = getEditor();
    Lay.BLtg(view, "N", Lay.BL("W", Lay.BxL("H", Lay.BL("N", panelList), Box.createHorizontalStrut(5), Lay.BL("N", editor))));
    if (list.getModel().getSize() > 0)
        list.setSelectedIndex(0);
    return scrollPane;
}
Also used : JScrollPane(javax.swing.JScrollPane) JPanel(javax.swing.JPanel) ActionMap(javax.swing.ActionMap) ActionEvent(java.awt.event.ActionEvent) ListSelectionEvent(javax.swing.event.ListSelectionEvent) Host(gov.sandia.n2a.host.Host) ListSelectionListener(javax.swing.event.ListSelectionListener) DefaultListCellRenderer(javax.swing.DefaultListCellRenderer) InputMap(javax.swing.InputMap) Component(java.awt.Component) AbstractAction(javax.swing.AbstractAction)

Example 5 with Host

use of gov.sandia.n2a.host.Host in project n2a by frothga.

the class Main method runHeadless.

/**
 *        Assumes this app was started solely for the purpose of running one specific job.
 *        This job operates outside the normal job management. The user is responsible
 *        for everything, including load balancing, directory and file management.
 *        Jobs can run remotely, but there is no support for retrieving results.
 */
public static void runHeadless(MNode record) {
    // See PanelEquations.launchJob()
    // Use current working directory, on assumption that's what the caller wants.
    Path jobDir = Paths.get(System.getProperty("user.dir")).toAbsolutePath();
    // This allows a remote job to run in the regular jobs directory there.
    String jobKey = new SimpleDateFormat("yyyy-MM-dd-HHmmss", Locale.ROOT).format(new Date());
    // Make this appear as if it is from the jobs collection.
    MDoc job = new MDoc(jobDir.resolve("job"), jobKey);
    String key = record.key();
    MNode doc = AppData.models.childOrEmpty(key);
    record.mergeUnder(doc);
    // TODO: the only reason to collate here is to ensure that host and backend are correctly identified if they are inherited. Need a more efficient method, such as lazy collation in MPart.
    MPart collated = new MPart(record);
    NodeJob.collectJobParameters(collated, key, job);
    NodeJob.saveSnapshot(record, job);
    // Handle remote host
    // If a remote host is used, it must be specified exactly, rather than a list of possibilities.
    Host host = Host.get(job);
    if (// Need to note the key so user can easily find the remote job directory.
    host instanceof Remote) {
        job.set(jobKey, "remoteKey");
        job.save();
    }
    // Start the job.
    Backend backend = Backend.getBackend(job.get("backend"));
    backend.start(job);
    // Wait for completion
    NodeJob node = new NodeJobHeadless(job);
    while (node.complete < 1) node.monitorProgress();
    // Convert to CSV, if requested.
    if (record.getFlag("$metadata", "csv")) {
        Table table = new Table(jobDir.resolve("out"), false);
        try {
            table.dumpCSV(jobDir.resolve("out.csv"));
        } catch (IOException e) {
        }
    }
    // Extract results requested in ASV
    MNode ASV = record.child("$metadata", "dakota", "ASV");
    // nothing more to do
    if (ASV == null)
        return;
    OutputParser output = new OutputParser();
    output.parse(jobDir.resolve("out"));
    try (BufferedWriter writer = Files.newBufferedWriter(jobDir.resolve("results"))) {
        for (MNode o : ASV) {
            String name = o.get();
            Column c = output.getColumn(name);
            float value = 0;
            if (c != null && !c.values.isEmpty())
                value = c.values.get(c.values.size() - 1);
            writer.write(value + " " + name);
        }
    } catch (IOException e) {
    }
}
Also used : Path(java.nio.file.Path) MPart(gov.sandia.n2a.eqset.MPart) Table(gov.sandia.n2a.ui.jobs.Table) Remote(gov.sandia.n2a.host.Remote) Host(gov.sandia.n2a.host.Host) IOException(java.io.IOException) MNode(gov.sandia.n2a.db.MNode) Date(java.util.Date) MDoc(gov.sandia.n2a.db.MDoc) BufferedWriter(java.io.BufferedWriter) Backend(gov.sandia.n2a.plugins.extpoints.Backend) Column(gov.sandia.n2a.ui.jobs.OutputParser.Column) NodeJob(gov.sandia.n2a.ui.jobs.NodeJob) OutputParser(gov.sandia.n2a.ui.jobs.OutputParser) SimpleDateFormat(java.text.SimpleDateFormat)

Aggregations

Host (gov.sandia.n2a.host.Host)13 Path (java.nio.file.Path)8 MNode (gov.sandia.n2a.db.MNode)7 Remote (gov.sandia.n2a.host.Remote)5 IOException (java.io.IOException)5 TreePath (javax.swing.tree.TreePath)5 Date (java.util.Date)4 MDoc (gov.sandia.n2a.db.MDoc)3 Backend (gov.sandia.n2a.plugins.extpoints.Backend)3 NodeJob (gov.sandia.n2a.ui.jobs.NodeJob)3 BufferedWriter (java.io.BufferedWriter)3 MPart (gov.sandia.n2a.eqset.MPart)2 ExtensionPoint (gov.sandia.n2a.plugins.ExtensionPoint)2 Table (gov.sandia.n2a.ui.jobs.Table)2 ActionEvent (java.awt.event.ActionEvent)2 SimpleDateFormat (java.text.SimpleDateFormat)2 AbstractAction (javax.swing.AbstractAction)2 ActionMap (javax.swing.ActionMap)2 InputMap (javax.swing.InputMap)2 JPanel (javax.swing.JPanel)2