Search in sources :

Example 1 with RemoverFn

use of io.deephaven.web.shared.fu.RemoverFn in project deephaven-core by deephaven.

the class JsFigureFactory method create.

private static Promise<JsFigure> create(JsFigureDescriptor descriptor) {
    JsArray<JsTable> tables = descriptor.getTables();
    if (tables == null || tables.length == 0) {
        return (Promise<JsFigure>) (Promise) Promise.reject("No tables provided for Figure creation");
    }
    FigureDescriptor figureDescriptor = convertJsFigureDescriptor(descriptor);
    FetchObjectResponse response = new FetchObjectResponse();
    response.setData(figureDescriptor.serializeBinary());
    Promise<?>[] tableCopyPromises = tables.map((table, index, all) -> table.copy(false)).asArray(new Promise[0]);
    return Promise.all(tableCopyPromises).then(unknownTableCopies -> {
        JsArray<JsTable> jsTableCopies = Js.cast(unknownTableCopies);
        JsTable[] tableCopies = jsTableCopies.asArray(new JsTable[0]);
        return new JsFigure(c -> c.apply(null, response), (figure, descriptor1) -> {
            // We need to listen for disconnects and reconnects
            boolean[] isTableDisconnected = new boolean[tableCopies.length];
            ArrayList<RemoverFn> removerFns = new ArrayList<>(tableCopies.length * 3);
            for (int i = 0; i < tableCopies.length; i++) {
                final int tableIndex = i;
                // Tables are closed when the figure is closed, no need to remove listeners later
                removerFns.add(tableCopies[i].addEventListener(JsTable.EVENT_DISCONNECT, ignore -> {
                    isTableDisconnected[tableIndex] = true;
                    for (int j = 0; j < isTableDisconnected.length; j++) {
                        if (isTableDisconnected[j] && j != tableIndex) {
                            return;
                        }
                    }
                    figure.fireEvent(JsFigure.EVENT_DISCONNECT);
                    figure.unsubscribe();
                }));
                removerFns.add(tableCopies[i].addEventListener(JsTable.EVENT_RECONNECT, ignore -> {
                    isTableDisconnected[tableIndex] = false;
                    for (int j = 0; j < isTableDisconnected.length; j++) {
                        if (isTableDisconnected[j]) {
                            return;
                        }
                    }
                    try {
                        figure.verifyTables();
                        figure.fireEvent(JsFigure.EVENT_RECONNECT);
                        figure.enqueueSubscriptionCheck();
                    } catch (JsFigure.FigureSourceException e) {
                        final CustomEventInit init = CustomEventInit.create();
                        init.setDetail(e);
                        figure.fireEvent(JsFigure.EVENT_RECONNECTFAILED, init);
                    }
                }));
                removerFns.add(tableCopies[i].addEventListener(JsTable.EVENT_RECONNECTFAILED, err -> {
                    for (RemoverFn removerFn : removerFns) {
                        removerFn.remove();
                    }
                    figure.unsubscribe();
                    final CustomEventInit init = CustomEventInit.create();
                    init.setDetail(err);
                    figure.fireEvent(JsFigure.EVENT_RECONNECTFAILED, init);
                }));
            }
            return Promise.resolve(new JsFigure.FigureTableFetchData(tableCopies, new TableMap[0], Collections.emptyMap()));
        }).refetch();
    });
}
Also used : IThenable(elemental2.promise.IThenable) TableMap(io.deephaven.web.client.api.TableMap) RemoverFn(io.deephaven.web.shared.fu.RemoverFn) FigureDescriptor(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.FigureDescriptor) JsMethod(jsinterop.annotations.JsMethod) HashMap(java.util.HashMap) CustomEventInit(elemental2.dom.CustomEventInit) Promise(elemental2.promise.Promise) JsPropertyMap(jsinterop.base.JsPropertyMap) JsArray(elemental2.core.JsArray) ArrayList(java.util.ArrayList) Js(jsinterop.base.Js) FetchObjectResponse(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectResponse) JsTable(io.deephaven.web.client.api.JsTable) Map(java.util.Map) Collections(java.util.Collections) io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.figuredescriptor(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.figuredescriptor) ArrayList(java.util.ArrayList) Promise(elemental2.promise.Promise) JsTable(io.deephaven.web.client.api.JsTable) RemoverFn(io.deephaven.web.shared.fu.RemoverFn) CustomEventInit(elemental2.dom.CustomEventInit) FetchObjectResponse(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectResponse) FigureDescriptor(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.FigureDescriptor)

Example 2 with RemoverFn

use of io.deephaven.web.shared.fu.RemoverFn in project deephaven-core by deephaven.

the class JsTable method fetchTotals.

private Promise<JsTotalsTable> fetchTotals(Object config, JsProvider<ClientTableState> state) {
    JsTotalsTableConfig directive = getTotalsDirectiveFromOptionalConfig(config);
    ClientTableState[] lastGood = { null };
    final JsTableFetch totalsFactory = (callback, newState, metadata) -> {
        final ClientTableState target;
        // we know this will get called at least once, immediately, so lastGood will never be null
        if (isClosed()) {
            // source table was closed, we have to rely on lastGood...
            target = lastGood[0];
        } else {
            target = state.valueOf();
            // make sure we are only retained by one state at a time
            // TODO: refactor subscription system to handle non-JsTable subscriptions w/ same one:one semantics,
            target.retain(directive);
            if (lastGood[0] != null && lastGood[0] != target) {
                lastGood[0].unretain(directive);
            }
            lastGood[0] = target;
        }
        JsLog.debug("Sending totals table fetch ", directive, " for ", target, "(", LazyString.of(target::getHandle), "), into ", LazyString.of(newState::getHandle), "(", newState, ")");
        // );
        throw new UnsupportedOperationException("totalsTables");
    };
    String summary = "totals table " + directive + ", " + directive.groupBy.join(",");
    final ClientTableState totals = workerConnection.newState(totalsFactory, summary);
    final LazyPromise<JsTotalsTable> result = new LazyPromise<>();
    boolean[] downsample = { true };
    return // lastGood will always be non-null after this
    totals.refetch(this, workerConnection.metadata()).then(ready -> {
        JsTable wrapped = new JsTable(workerConnection, ready);
        // technically this is overkill, but it is more future-proofed than only listening for column
        // changes
        final RemoverFn remover = addEventListener(INTERNAL_EVENT_STATECHANGED, e -> {
            // which simply accrues state until the user decides to commit the modification).
            if (downsample[0]) {
                downsample[0] = false;
                LazyPromise.runLater(() -> {
                    if (wrapped.isClosed()) {
                        return;
                    }
                    downsample[0] = true;
                    // IDS-2684 - comment out the four lines above to reproduce
                    // when ever the main table changes its state, reload the totals table from the
                    // new state
                    final ClientTableState existing = wrapped.state();
                    final ClientTableState nextState = workerConnection.newState(totalsFactory, summary);
                    JsLog.debug("Rebasing totals table", existing, " -> ", nextState, " for ", wrapped);
                    wrapped.setState(nextState);
                    // If the wrapped table's state has changed (any filter / sort / columns
                    // applied),
                    // then we'll want to re-apply these conditions on top of the newly set state.
                    final boolean needsMutation = !existing.isEqual(ready);
                    final ThenOnFulfilledCallbackFn restoreVp = running -> {
                        // now that we've (possibly) updated selection conditions, put back in any
                        // viewport.
                        result.onSuccess(JsTotalsTable::refreshViewport);
                        return null;
                    };
                    final Promise<ClientTableState> promise = nextState.refetch(this, workerConnection.metadata());
                    if (needsMutation) {
                        // nextState will be empty, so we might want to test for
                        // isEmpty() instead
                        wrapped.batch(b -> b.setConfig(existing)).then(restoreVp);
                    } else {
                        promise.then(restoreVp);
                    }
                // IDS-2684 - Comment out the two lines below to reproduce
                });
            }
        });
        wrapped.onClosed.add(remover::remove);
        wrapped.onClosed.add(() -> lastGood[0].unretain(directive));
        onClosed.add(remover::remove);
        final JsTotalsTable totalsTable = new JsTotalsTable(wrapped, directive.serialize(), directive.groupBy);
        result.succeed(totalsTable);
        return result.asPromise();
    });
}
Also used : JsInputTable(io.deephaven.web.client.api.input.JsInputTable) ActiveTableBinding(io.deephaven.web.client.state.ActiveTableBinding) LazyPromise.logError(io.deephaven.web.client.fu.LazyPromise.logError) JsPropertyMap(jsinterop.base.JsPropertyMap) ThenOnFulfilledCallbackFn(elemental2.promise.IThenable.ThenOnFulfilledCallbackFn) ZoomRange(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.runchartdownsamplerequest.ZoomRange) io.deephaven.web.shared.data(io.deephaven.web.shared.data) SelectDistinctRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.SelectDistinctRequest) FilterCondition(io.deephaven.web.client.api.filter.FilterCondition) JsData(io.deephaven.web.client.fu.JsData) JsLog(io.deephaven.web.client.fu.JsLog) ViewportData(io.deephaven.web.client.api.subscription.ViewportData) ClientTableState(io.deephaven.web.client.state.ClientTableState) JsArray(elemental2.core.JsArray) HasTableBinding(io.deephaven.web.client.state.HasTableBinding) Stream(java.util.stream.Stream) HasLifecycle(io.deephaven.web.client.api.lifecycle.HasLifecycle) TableSubscription(io.deephaven.web.client.api.subscription.TableSubscription) MergeResults(io.deephaven.web.client.api.subscription.ViewportData.MergeResults) AsOfJoinTablesRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.AsOfJoinTablesRequest) Global(elemental2.core.Global) JsRunnable(io.deephaven.web.shared.fu.JsRunnable) JsItr(io.deephaven.web.client.fu.JsItr) java.util(java.util) JsOptional(jsinterop.annotations.JsOptional) RemoverFn(io.deephaven.web.shared.fu.RemoverFn) NaturalJoinTablesRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.NaturalJoinTablesRequest) RunChartDownsampleRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.RunChartDownsampleRequest) ColumnData(io.deephaven.web.shared.data.columns.ColumnData) JsMethod(jsinterop.annotations.JsMethod) Promise(elemental2.promise.Promise) JsTreeTableConfig(io.deephaven.web.client.api.tree.JsTreeTableConfig) StateCache(io.deephaven.web.client.api.state.StateCache) SnapshotType(io.deephaven.web.shared.data.TableSnapshot.SnapshotType) RequestBatcher(io.deephaven.web.client.api.batch.RequestBatcher) JsProperty(jsinterop.annotations.JsProperty) Js(jsinterop.base.Js) TableAttributesDefinition(io.deephaven.web.client.api.barrage.def.TableAttributesDefinition) TableViewportSubscription(io.deephaven.web.client.api.subscription.TableViewportSubscription) JsRollupConfig(io.deephaven.web.client.api.tree.JsRollupConfig) ViewportRow(io.deephaven.web.client.api.subscription.ViewportRow) ExactJoinTablesRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.ExactJoinTablesRequest) JsTreeTable(io.deephaven.web.client.api.tree.JsTreeTable) LazyPromise(io.deephaven.web.client.fu.LazyPromise) JsProvider(io.deephaven.web.shared.fu.JsProvider) JsConsumer(io.deephaven.web.shared.fu.JsConsumer) DomGlobal(elemental2.dom.DomGlobal) CustomEventInit(elemental2.dom.CustomEventInit) NO_ROW_FORMAT_COLUMN(io.deephaven.web.client.api.subscription.ViewportData.NO_ROW_FORMAT_COLUMN) ColumnDefinition(io.deephaven.web.client.api.barrage.def.ColumnDefinition) SnapshotTableRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.SnapshotTableRequest) CrossJoinTablesRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.CrossJoinTablesRequest) ThenOnFulfilledCallbackFn(elemental2.promise.IThenable.ThenOnFulfilledCallbackFn) LazyPromise(io.deephaven.web.client.fu.LazyPromise) ClientTableState(io.deephaven.web.client.state.ClientTableState) RemoverFn(io.deephaven.web.shared.fu.RemoverFn)

Aggregations

JsArray (elemental2.core.JsArray)2 CustomEventInit (elemental2.dom.CustomEventInit)2 Promise (elemental2.promise.Promise)2 Global (elemental2.core.Global)1 DomGlobal (elemental2.dom.DomGlobal)1 IThenable (elemental2.promise.IThenable)1 ThenOnFulfilledCallbackFn (elemental2.promise.IThenable.ThenOnFulfilledCallbackFn)1 FigureDescriptor (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.FigureDescriptor)1 io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.figuredescriptor (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.figuredescriptor)1 FetchObjectResponse (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectResponse)1 AsOfJoinTablesRequest (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.AsOfJoinTablesRequest)1 CrossJoinTablesRequest (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.CrossJoinTablesRequest)1 ExactJoinTablesRequest (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.ExactJoinTablesRequest)1 NaturalJoinTablesRequest (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.NaturalJoinTablesRequest)1 RunChartDownsampleRequest (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.RunChartDownsampleRequest)1 SelectDistinctRequest (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.SelectDistinctRequest)1 SnapshotTableRequest (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.SnapshotTableRequest)1 ZoomRange (io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.runchartdownsamplerequest.ZoomRange)1 JsTable (io.deephaven.web.client.api.JsTable)1 TableMap (io.deephaven.web.client.api.TableMap)1