Search in sources :

Example 1 with Pointer

use of org.knime.core.util.Pointer in project knime-core by knime.

the class DefaultNodeProgressMonitorTest method internalTestManyMessageEvents.

/**
 * A lot of incremental numeric progress updates + many message events
 * Previously, this took significantly longer due to expensive string construction.
 */
private void internalTestManyMessageEvents(final NodeProgressMonitor toMonitor, final NodeProgressMonitor toControl) throws Exception {
    final int parts = 1000000;
    final MutableLong stringComposeCounter = new MutableLong();
    Function<Integer, String> msgFct = (index) -> {
        stringComposeCounter.increment();
        return "Row " + index + " (Row \"" + RowKey.createRowKey((long) index) + "\")";
    };
    final Pointer<NodeProgress> progressPointer = new Pointer<>();
    String lastExpectedMsg = msgFct.apply(parts);
    final Function<NodeProgress, Boolean> isLastEventFunction = p -> p.getMessage().equals(lastExpectedMsg);
    NodeProgressListener l = createListener(progressPointer, isLastEventFunction);
    toMonitor.addProgressListener(l);
    try {
        for (int i = 1; i < parts + 1; i++) {
            final int index = i;
            // if this line is replaced by a direct string composition this takes an order of magnitude longer
            toControl.setProgress(i / (double) parts, () -> msgFct.apply(index));
        }
        synchronized (isLastEventFunction) {
            isLastEventFunction.wait(500);
        }
        assertThat(progressPointer.get().getProgress(), is(closeTo(1.0, PROG_EPSILON)));
        assertThat(progressPointer.get().getMessage(), is(equalTo(lastExpectedMsg)));
        // the lazy string creation should only be called 4 times a second at most,
        // it must be at least two - one for the reference string creation and one during an event
        Assert.assertThat(stringComposeCounter.getValue(), is(allOf(greaterThanOrEqualTo(2L), lessThan(5L))));
    } finally {
        toMonitor.removeProgressListener(l);
    }
}
Also used : Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) RowKey(org.knime.core.data.RowKey) Matchers.allOf(org.hamcrest.Matchers.allOf) Test(org.junit.Test) Function(java.util.function.Function) NodeProgressEvent(org.knime.core.node.workflow.NodeProgressEvent) Assert.assertThat(org.junit.Assert.assertThat) Matchers.closeTo(org.hamcrest.Matchers.closeTo) NodeProgressListener(org.knime.core.node.workflow.NodeProgressListener) MutableLong(org.apache.commons.lang3.mutable.MutableLong) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Matchers.lessThan(org.hamcrest.Matchers.lessThan) Matchers.is(org.hamcrest.Matchers.is) Assert(org.junit.Assert) SubNodeProgressMonitor(org.knime.core.node.DefaultNodeProgressMonitor.SubNodeProgressMonitor) Pointer(org.knime.core.util.Pointer) NodeProgress(org.knime.core.node.workflow.NodeProgress) MutableLong(org.apache.commons.lang3.mutable.MutableLong) NodeProgressListener(org.knime.core.node.workflow.NodeProgressListener) NodeProgress(org.knime.core.node.workflow.NodeProgress) Pointer(org.knime.core.util.Pointer)

Example 2 with Pointer

use of org.knime.core.util.Pointer in project knime-core by knime.

the class DefaultNodeProgressMonitorTest method internalTestManySmallIncrements.

/**
 * Just a lot of incremental numeric progress updates.
 */
private void internalTestManySmallIncrements(final NodeProgressMonitor toMonitor, final NodeProgressMonitor toControl) throws Exception {
    final Pointer<NodeProgress> progressPointer = new Pointer<>();
    final Function<NodeProgress, Boolean> isLastEventFunction = p -> p.getProgress() >= 1.0 - PROG_EPSILON;
    NodeProgressListener l = createListener(progressPointer, isLastEventFunction);
    toMonitor.addProgressListener(l);
    try {
        int parts = 10000000;
        for (int i = 0; i < parts; i++) {
            toControl.setProgress((i + 1) / (double) parts);
        }
        synchronized (isLastEventFunction) {
            isLastEventFunction.wait(1000);
        }
        assertThat(progressPointer.get().getProgress(), is(closeTo(1.0, PROG_EPSILON)));
    } finally {
        toMonitor.removeProgressListener(l);
    }
}
Also used : Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) RowKey(org.knime.core.data.RowKey) Matchers.allOf(org.hamcrest.Matchers.allOf) Test(org.junit.Test) Function(java.util.function.Function) NodeProgressEvent(org.knime.core.node.workflow.NodeProgressEvent) Assert.assertThat(org.junit.Assert.assertThat) Matchers.closeTo(org.hamcrest.Matchers.closeTo) NodeProgressListener(org.knime.core.node.workflow.NodeProgressListener) MutableLong(org.apache.commons.lang3.mutable.MutableLong) Matchers.equalTo(org.hamcrest.Matchers.equalTo) Matchers.lessThan(org.hamcrest.Matchers.lessThan) Matchers.is(org.hamcrest.Matchers.is) Assert(org.junit.Assert) SubNodeProgressMonitor(org.knime.core.node.DefaultNodeProgressMonitor.SubNodeProgressMonitor) Pointer(org.knime.core.util.Pointer) NodeProgress(org.knime.core.node.workflow.NodeProgress) NodeProgressListener(org.knime.core.node.workflow.NodeProgressListener) NodeProgress(org.knime.core.node.workflow.NodeProgress) Pointer(org.knime.core.util.Pointer)

Example 3 with Pointer

use of org.knime.core.util.Pointer in project knime-core by knime.

the class WorkflowEditor method saveTo.

/**
 * Save workflow to resource.
 *
 * @param fileResource .. the resource, usually m_fileResource or m_autoSaveFileResource or soon-to-be
 *            m_fileResource (for save-as)
 * @param monitor ...
 * @param saveWithData ... save data also
 * @param newContext a new workflow context for the saved workflow; if this is non-<code>null</code>, a "save as" is
 *            performed
 */
private void saveTo(final URI fileResource, final IProgressMonitor monitor, final boolean saveWithData, final WorkflowContext newContext) {
    LOGGER.debug("Saving workflow " + getWorkflowManager().get().getNameWithID());
    // Exception messages from the inner thread
    final StringBuilder exceptionMessage = new StringBuilder();
    if (fileResource == null && m_parentEditor != null) {
        m_parentEditor.doSave(monitor);
        m_isDirty = false;
        Display.getDefault().asyncExec(new Runnable() {

            @Override
            public void run() {
                firePropertyChange(IEditorPart.PROP_DIRTY);
            }
        });
        return;
    }
    // attach editor properties with the workflow manager - for all sub editors too
    saveEditorSettingsToWorkflowManager();
    /* TODO: EditorSettings should be saved on all child editors too. But this triggers them dirty. And they stay
         * dirty even after save (and setting them clean!). The dirty flag is a mess. Needs to be cleaned up!
         * And after that, we may not inherit the zoom level (in metanodes) from the parent anymore
         * (see #applyEditorSettingsFromWorkflowManager).
         * for (IEditorPart subEditor : getSubEditors()) {
         *   ((WorkflowEditor)subEditor).saveEditorSettingsToWorkflowManager();
         * }
         */
    // to be sure to mark dirty and inform the user about running nodes
    // we ask for the state BEFORE saving
    // this flag is evaluated at the end of this method
    boolean wasInProgress = false;
    try {
        final File workflowDir = new File(fileResource);
        AbstractSaveRunnable saveRunnable;
        if (newContext != null) {
            saveRunnable = new SaveAsRunnable(this, exceptionMessage, monitor, newContext);
        } else {
            WorkflowSaveHelper saveHelper = new WorkflowSaveHelper(saveWithData, false);
            saveRunnable = new InplaceSaveRunnable(this, exceptionMessage, saveHelper, monitor, workflowDir);
        }
        IWorkbench wb = PlatformUI.getWorkbench();
        IProgressService ps = wb.getProgressService();
        NodeContainerState state = m_manager.getNodeContainerState();
        wasInProgress = state.isExecutionInProgress() && !state.isExecutingRemotely();
        ps.run(true, false, saveRunnable);
        // this code is usually (always?) run in the UI thread but in case it's not we schedule in UI thread
        // (SVG export always in UI thread)
        final File svgFile = new File(workflowDir, WorkflowPersistor.SVG_WORKFLOW_FILE);
        svgFile.delete();
        Display.getDefault().syncExec(new Runnable() {

            @Override
            public void run() {
                if (m_manager.isProject()) {
                    saveSVGImage(svgFile);
                }
            }
        });
        // mark command stack (no undo beyond this point)
        getCommandStack().markSaveLocation();
    } catch (Exception e) {
        LOGGER.error("Could not save workflow: " + exceptionMessage, e);
        // inform the user
        if (exceptionMessage.length() > 0) {
            showInfoMessage("Workflow could not be saved ...", exceptionMessage.toString());
        }
        throw new OperationCanceledException("Workflow was not saved: " + exceptionMessage.toString());
    }
    Display.getDefault().asyncExec(new Runnable() {

        @Override
        public void run() {
            if (!Display.getDefault().isDisposed() && (m_manager != null)) {
                // mark all sub editors as saved
                for (IEditorPart subEditor : getSubEditors()) {
                    final WorkflowEditor editor = (WorkflowEditor) subEditor;
                    ((WorkflowEditor) subEditor).setIsDirty(false);
                    editor.firePropertyChange(IEditorPart.PROP_DIRTY);
                }
            }
        }
    });
    monitor.done();
    // or simply saves (Ctrl+S)
    if (wasInProgress) {
        markDirty();
        final Pointer<Boolean> abortPointer = new Pointer<Boolean>();
        abortPointer.set(Boolean.FALSE);
        Display.getDefault().syncExec(new Runnable() {

            @Override
            public void run() {
                boolean abort = false;
                Shell sh = Display.getDefault().getActiveShell();
                String title = "Workflow in execution";
                String message = "Executing nodes are not saved!";
                if (m_isClosing) {
                    abort = !MessageDialog.openQuestion(sh, title, message + " Exit anyway?");
                    // user canceled close
                    m_isClosing = !abort;
                } else {
                    IPreferenceStore prefStore = KNIMEUIPlugin.getDefault().getPreferenceStore();
                    String toogleMessage = "Don't warn me again";
                    if (prefStore.getBoolean(PreferenceConstants.P_CONFIRM_EXEC_NODES_NOT_SAVED)) {
                        MessageDialogWithToggle.openInformation(sh, title, message, toogleMessage, false, prefStore, PreferenceConstants.P_CONFIRM_EXEC_NODES_NOT_SAVED);
                    }
                }
                abortPointer.set(Boolean.valueOf(abort));
            }
        });
        if (abortPointer.get()) {
            throw new OperationCanceledException("Closing workflow canceled on user request.");
        }
    }
}
Also used : OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) Pointer(org.knime.core.util.Pointer) IEditorPart(org.eclipse.ui.IEditorPart) OperationCanceledException(org.eclipse.core.runtime.OperationCanceledException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) CoreException(org.eclipse.core.runtime.CoreException) PartInitException(org.eclipse.ui.PartInitException) InvocationTargetException(java.lang.reflect.InvocationTargetException) IWorkbench(org.eclipse.ui.IWorkbench) NodeContainerState(org.knime.core.node.workflow.NodeContainerState) Shell(org.eclipse.swt.widgets.Shell) WorkflowSaveHelper(org.knime.core.node.workflow.WorkflowSaveHelper) IProgressService(org.eclipse.ui.progress.IProgressService) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) IPreferenceStore(org.eclipse.jface.preference.IPreferenceStore) ReferencedFile(org.knime.core.internal.ReferencedFile) File(java.io.File)

Aggregations

Pointer (org.knime.core.util.Pointer)3 Function (java.util.function.Function)2 MutableLong (org.apache.commons.lang3.mutable.MutableLong)2 Matchers.allOf (org.hamcrest.Matchers.allOf)2 Matchers.closeTo (org.hamcrest.Matchers.closeTo)2 Matchers.equalTo (org.hamcrest.Matchers.equalTo)2 Matchers.greaterThanOrEqualTo (org.hamcrest.Matchers.greaterThanOrEqualTo)2 Matchers.is (org.hamcrest.Matchers.is)2 Matchers.lessThan (org.hamcrest.Matchers.lessThan)2 Assert (org.junit.Assert)2 Assert.assertThat (org.junit.Assert.assertThat)2 Test (org.junit.Test)2 RowKey (org.knime.core.data.RowKey)2 SubNodeProgressMonitor (org.knime.core.node.DefaultNodeProgressMonitor.SubNodeProgressMonitor)2 NodeProgress (org.knime.core.node.workflow.NodeProgress)2 NodeProgressEvent (org.knime.core.node.workflow.NodeProgressEvent)2 NodeProgressListener (org.knime.core.node.workflow.NodeProgressListener)2 File (java.io.File)1 IOException (java.io.IOException)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1