Search in sources :

Example 1 with ClientTableState

use of io.deephaven.web.client.state.ClientTableState in project deephaven-core by deephaven.

the class JsTable method setState.

@Override
public void setState(final ClientTableState state) {
    state.onRunning(s -> {
        if (state == currentState) {
            lastVisibleState = state;
            hasInputTable = s.getTableDef().getAttributes().isInputTable();
            // defer the size change so that is there is a viewport sub also waiting for onRunning, it gets it first
            LazyPromise.runLater(() -> {
                if (state == state()) {
                    setSize(state.getSize());
                }
            });
        }
    }, JsRunnable.doNothing());
    final ClientTableState was = currentState;
    if (was != state) {
        state.onRunning(s -> {
            // If already closed, we can ignore this, since we already cleaned those up
            if (!isClosed() && was != null && was != state()) {
                // if we held a subscription
                TableViewportSubscription existingSubscription = subscriptions.remove(was.getHandle());
                if (existingSubscription != null && existingSubscription.getStatus() != TableViewportSubscription.Status.DONE) {
                    JsLog.debug("closing old viewport", state(), existingSubscription.state());
                    // with the replacement state successfully running, we can shut down the old viewport (unless
                    // something
                    // external retained it)
                    existingSubscription.internalClose();
                }
            }
        }, JsRunnable.doNothing());
        boolean historyChanged = false;
        if (was != null) {
            // check if the new state is derived from the current state
            historyChanged = !state.isAncestor(was);
            was.pause(this);
            JsLog.debug("Table state change (new history? ", historyChanged, ") " + "from ", was.getHandle().toString(), was, " to ", state.getHandle().toString(), state);
        }
        currentState = state;
        ActiveTableBinding active = state.getActiveBinding(this);
        if (active == null) {
            state.createBinding(this);
        } else {
            active.changeState(state);
        }
        if (historyChanged) {
            // when the new state is not derived from the current state,
            // then, when the new state succeeds, we will totally releaseTable the previous table,
            // allowing it to be automatically released (if nobody else needs it).
            state.onRunning(success -> {
                if (isClosed()) {
                    // if already closed, we should have already released that handle too
                    return;
                }
                if (currentState != state) {
                    // ancestor
                    return;
                }
                final boolean shouldRelease = !state().isAncestor(was);
                JsLog.debug("History changing state update complete; release? ", shouldRelease, " state: ", was, LazyString.of(was::toStringMinimal));
                if (shouldRelease) {
                    was.releaseTable(this);
                }
            }, () -> {
                LazyPromise.runLater(() -> {
                    if (isClosed()) {
                        // if already closed, we should have already released that handle too
                        return;
                    }
                    if (currentState != state) {
                        // ancestor
                        return;
                    }
                    final boolean shouldRelease = !currentState.isAncestor(was);
                    JsLog.debug("History changing state update failed; release? ", shouldRelease, " state: ", was, LazyString.of(was::toStringMinimal));
                    if (shouldRelease) {
                        was.releaseTable(this);
                    }
                });
            });
        }
        final CustomEventInit init = CustomEventInit.create();
        init.setDetail(state);
        fireEvent(INTERNAL_EVENT_STATECHANGED, init);
    }
}
Also used : ActiveTableBinding(io.deephaven.web.client.state.ActiveTableBinding) ClientTableState(io.deephaven.web.client.state.ClientTableState) CustomEventInit(elemental2.dom.CustomEventInit) TableViewportSubscription(io.deephaven.web.client.api.subscription.TableViewportSubscription)

Example 2 with ClientTableState

use of io.deephaven.web.client.state.ClientTableState in project deephaven-core by deephaven.

the class JsTable method getInternalViewportData.

public Promise<TableData> getInternalViewportData() {
    final LazyPromise<TableData> promise = new LazyPromise<>();
    final ClientTableState active = state();
    active.onRunning(state -> {
        if (currentViewportData == null) {
            // no viewport data received yet; let's setup a one-shot UPDATED event listener
            addEventListenerOneShot(EVENT_UPDATED, ignored -> promise.succeed(currentViewportData));
        } else {
            promise.succeed(currentViewportData);
        }
    }, promise::fail, () -> promise.fail("Table closed before viewport data was read"));
    return promise.asPromise(MAX_BATCH_TIME);
}
Also used : ClientTableState(io.deephaven.web.client.state.ClientTableState) LazyPromise(io.deephaven.web.client.fu.LazyPromise)

Example 3 with ClientTableState

use of io.deephaven.web.client.state.ClientTableState in project deephaven-core by deephaven.

the class JsTable method copy.

@JsMethod
public Promise<JsTable> copy(boolean resolved) {
    if (resolved) {
        LazyPromise<ClientTableState> promise = new LazyPromise<>();
        final ClientTableState unresolved = state();
        unresolved.onRunning(promise::succeed, promise::fail, () -> promise.fail("Table failed or closed, copy could not complete"));
        return promise.asPromise(MAX_BATCH_TIME).then(s -> Promise.resolve(new JsTable(this)));
    }
    return Promise.resolve(new JsTable(this));
}
Also used : ClientTableState(io.deephaven.web.client.state.ClientTableState) LazyPromise(io.deephaven.web.client.fu.LazyPromise) JsMethod(jsinterop.annotations.JsMethod)

Example 4 with ClientTableState

use of io.deephaven.web.client.state.ClientTableState in project deephaven-core by deephaven.

the class WorkerConnection method flush.

private void flush() {
    // LATER: instead of running a bunch of serial operations,
    // condense these all into a single batch operation.
    // All three server calls made by this method are _only_ called by this method,
    // so we can reasonably merge all three into a single batched operation.
    ArrayList<ClientTableState> statesToFlush = new ArrayList<>(flushable);
    flushable.clear();
    for (ClientTableState state : statesToFlush) {
        if (state.hasNoSubscriptions()) {
            // yet completed (we leave orphaned nodes paused until a request completes).
            if (state.isSubscribed()) {
                state.setSubscribed(false);
                if (state.getHandle().isConnected()) {
                    BiDiStream<FlightData, FlightData> stream = subscriptionStreams.remove(state);
                    if (stream != null) {
                        stream.end();
                        stream.cancel();
                    }
                }
            }
            if (state.isEmpty()) {
                // completely empty; perform release
                final ClientTableState.ResolutionState previousState = state.getResolution();
                state.setResolution(ClientTableState.ResolutionState.RELEASED);
                state.setSubscribed(false);
                if (previousState != ClientTableState.ResolutionState.RELEASED) {
                    cache.release(state);
                    JsLog.debug("Releasing state", state, LazyString.of(state.getHandle()));
                    // don't send a release message to the server if the table isn't really there
                    if (state.getHandle().isConnected()) {
                        releaseHandle(state.getHandle());
                    }
                }
            }
        } else {
            List<TableSubscriptionRequest> vps = new ArrayList<>();
            state.forActiveSubscriptions((table, subscription) -> {
                assert table.isActive(state) : "Inactive table has a viewport still attached";
                vps.add(new TableSubscriptionRequest(table.getSubscriptionId(), subscription.getRows(), subscription.getColumns()));
            });
            boolean isViewport = vps.stream().allMatch(req -> req.getRows() != null);
            assert isViewport || vps.stream().noneMatch(req -> req.getRows() != null) : "All subscriptions to a given handle must be consistently viewport or non-viewport";
            BitSet includedColumns = vps.stream().map(TableSubscriptionRequest::getColumns).reduce((bs1, bs2) -> {
                BitSet result = new BitSet();
                result.or(bs1);
                result.or(bs2);
                return result;
            }).orElseThrow(() -> new IllegalStateException("Cannot call subscribe with zero subscriptions"));
            String[] columnTypes = Arrays.stream(state.getTableDef().getColumns()).map(ColumnDefinition::getType).toArray(String[]::new);
            state.setSubscribed(true);
            Builder subscriptionReq = new Builder(1024);
            double columnsOffset = BarrageSubscriptionRequest.createColumnsVector(subscriptionReq, makeUint8ArrayFromBitset(includedColumns));
            double viewportOffset = 0;
            if (isViewport) {
                viewportOffset = BarrageSubscriptionRequest.createViewportVector(subscriptionReq, serializeRanges(vps.stream().map(TableSubscriptionRequest::getRows).collect(Collectors.toSet())));
            }
            // TODO #188 support minUpdateIntervalMs
            double serializationOptionsOffset = BarrageSubscriptionOptions.createBarrageSubscriptionOptions(subscriptionReq, ColumnConversionMode.Stringify, true, 1000, 0);
            double tableTicketOffset = BarrageSubscriptionRequest.createTicketVector(subscriptionReq, state.getHandle().getTicket());
            BarrageSubscriptionRequest.startBarrageSubscriptionRequest(subscriptionReq);
            BarrageSubscriptionRequest.addColumns(subscriptionReq, columnsOffset);
            BarrageSubscriptionRequest.addSubscriptionOptions(subscriptionReq, serializationOptionsOffset);
            BarrageSubscriptionRequest.addViewport(subscriptionReq, viewportOffset);
            BarrageSubscriptionRequest.addTicket(subscriptionReq, tableTicketOffset);
            subscriptionReq.finish(BarrageSubscriptionRequest.endBarrageSubscriptionRequest(subscriptionReq));
            FlightData request = new FlightData();
            request.setAppMetadata(BarrageUtils.wrapMessage(subscriptionReq, BarrageMessageType.BarrageSubscriptionRequest));
            BiDiStream<FlightData, FlightData> stream = this.<FlightData, FlightData>streamFactory().create(headers -> flightServiceClient.doExchange(headers), (first, headers) -> browserFlightServiceClient.openDoExchange(first, headers), (next, headers, c) -> browserFlightServiceClient.nextDoExchange(next, headers, c::apply), new FlightData());
            stream.send(request);
            stream.onData(new JsConsumer<FlightData>() {

                @Override
                public void apply(FlightData data) {
                    ByteBuffer body = typedArrayToLittleEndianByteBuffer(data.getDataBody_asU8());
                    Message headerMessage = Message.getRootAsMessage(new io.deephaven.javascript.proto.dhinternal.flatbuffers.ByteBuffer(data.getDataHeader_asU8()));
                    if (body.limit() == 0 && headerMessage.headerType() != MessageHeader.RecordBatch) {
                        // TODO hang on to the schema to better handle the now-Utf8 columns
                        return;
                    }
                    RecordBatch header = headerMessage.header(new RecordBatch());
                    BarrageMessageWrapper barrageMessageWrapper = BarrageMessageWrapper.getRootAsBarrageMessageWrapper(new io.deephaven.javascript.proto.dhinternal.flatbuffers.ByteBuffer(data.getAppMetadata_asU8()));
                    if (barrageMessageWrapper.msgType() == BarrageMessageType.None) {
                        // continue previous message, just read RecordBatch
                        appendAndMaybeFlush(header, body);
                    } else {
                        assert barrageMessageWrapper.msgType() == BarrageMessageType.BarrageUpdateMetadata;
                        BarrageUpdateMetadata barrageUpdate = BarrageUpdateMetadata.getRootAsBarrageUpdateMetadata(new io.deephaven.javascript.proto.dhinternal.flatbuffers.ByteBuffer(new Uint8Array(barrageMessageWrapper.msgPayloadArray())));
                        startAndMaybeFlush(barrageUpdate.isSnapshot(), header, body, barrageUpdate, isViewport, columnTypes);
                    }
                }

                private DeltaUpdatesBuilder nextDeltaUpdates;

                private void appendAndMaybeFlush(RecordBatch header, ByteBuffer body) {
                    // using existing barrageUpdate, append to the current snapshot/delta
                    assert nextDeltaUpdates != null;
                    boolean shouldFlush = nextDeltaUpdates.appendRecordBatch(header, body);
                    if (shouldFlush) {
                        incrementalUpdates(state.getHandle(), nextDeltaUpdates.build());
                        nextDeltaUpdates = null;
                    }
                }

                private void startAndMaybeFlush(boolean isSnapshot, RecordBatch header, ByteBuffer body, BarrageUpdateMetadata barrageUpdate, boolean isViewport, String[] columnTypes) {
                    if (isSnapshot) {
                        TableSnapshot snapshot = createSnapshot(header, body, barrageUpdate, isViewport, columnTypes);
                        // for now we always expect snapshots to arrive in a single payload
                        initialSnapshot(state.getHandle(), snapshot);
                    } else {
                        nextDeltaUpdates = deltaUpdates(barrageUpdate, isViewport, columnTypes);
                        appendAndMaybeFlush(header, body);
                    }
                }
            });
            stream.onStatus(err -> {
                checkStatus(err);
                if (!err.isOk()) {
                    // TODO (core#1181): fix this hack that enables barrage errors to propagate to the UI widget
                    state.forActiveSubscriptions((table, subscription) -> {
                        table.failureHandled(err.getDetails());
                    });
                }
            });
            BiDiStream<FlightData, FlightData> oldStream = subscriptionStreams.put(state, stream);
            if (oldStream != null) {
                // cancel any old stream, we presently expect a fresh instance
                oldStream.end();
                oldStream.cancel();
            }
        }
    }
}
Also used : Arrays(java.util.Arrays) InitialTableDefinition(io.deephaven.web.client.api.barrage.def.InitialTableDefinition) LogSubscriptionRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.LogSubscriptionRequest) JsPropertyMap(jsinterop.base.JsPropertyMap) Buffer(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.schema_generated.org.apache.arrow.flatbuf.Buffer) HandshakeResponse(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.session_pb.HandshakeResponse) TypedTicket(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.TypedTicket) JsTimeZone(io.deephaven.web.client.api.i18n.JsTimeZone) ObjectServiceClient(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb_service.ObjectServiceClient) StackTrace(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.session_pb.terminationnotificationresponse.StackTrace) io.deephaven.web.shared.data(io.deephaven.web.shared.data) Map(java.util.Map) SessionServiceClient(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.session_pb_service.SessionServiceClient) FieldsChangeUpdate(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.application_pb.FieldsChangeUpdate) ListFieldsRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.application_pb.ListFieldsRequest) Set(java.util.Set) ClientTableState(io.deephaven.web.client.state.ClientTableState) ExportedTableCreationResponse(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.ExportedTableCreationResponse) JsArray(elemental2.core.JsArray) JsSet(elemental2.core.JsSet) Uint8Array(elemental2.core.Uint8Array) MetadataVersion(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.schema_generated.org.apache.arrow.flatbuf.MetadataVersion) JsVariableDefinition(io.deephaven.web.client.api.console.JsVariableDefinition) KeyValue(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.schema_generated.org.apache.arrow.flatbuf.KeyValue) ConsoleServiceClient(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb_service.ConsoleServiceClient) BarrageMessageWrapper(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageMessageWrapper) JsRunnable(io.deephaven.web.shared.fu.JsRunnable) JsItr(io.deephaven.web.client.fu.JsItr) JsOptional(jsinterop.annotations.JsOptional) JsWidget(io.deephaven.web.client.api.widget.JsWidget) JsFigure(io.deephaven.web.client.api.widget.plot.JsFigure) Promise(elemental2.promise.Promise) BiDiStream(io.deephaven.web.client.api.barrage.stream.BiDiStream) Supplier(java.util.function.Supplier) RequestBatcher(io.deephaven.web.client.api.batch.RequestBatcher) ArrayList(java.util.ArrayList) Builder(io.deephaven.javascript.proto.dhinternal.flatbuffers.Builder) ResponseStreamWrapper(io.deephaven.web.client.api.barrage.stream.ResponseStreamWrapper) BiConsumer(java.util.function.BiConsumer) TableReviver(io.deephaven.web.client.state.TableReviver) FetchObjectRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectRequest) JsTreeTable(io.deephaven.web.client.api.tree.JsTreeTable) TableServiceClient(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb_service.TableServiceClient) LazyPromise(io.deephaven.web.client.fu.LazyPromise) Nullable(javax.annotation.Nullable) BrowserHeaders(io.deephaven.javascript.proto.dhinternal.browserheaders.BrowserHeaders) LogSubscriptionData(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.console_pb.LogSubscriptionData) Ticket(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.ticket_pb.Ticket) ColumnDefinition(io.deephaven.web.client.api.barrage.def.ColumnDefinition) RecordBatch(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.RecordBatch) MergeTablesRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.MergeTablesRequest) ApplyPreviewColumnsRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.ApplyPreviewColumnsRequest) InputTableServiceClient(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.inputtable_pb_service.InputTableServiceClient) BarrageSubscriptionOptions(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageSubscriptionOptions) ColumnConversionMode(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.ColumnConversionMode) EmptyTableRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.EmptyTableRequest) BarrageUpdateMetadata(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageUpdateMetadata) ByteBuffer(java.nio.ByteBuffer) TableConfig(io.deephaven.web.client.api.batch.TableConfig) TableReference(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.TableReference) JsVariableChanges(io.deephaven.web.client.api.console.JsVariableChanges) ReleaseRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.session_pb.ReleaseRequest) FlightData(io.deephaven.javascript.proto.dhinternal.arrow.flight.protocol.flight_pb.FlightData) ApplicationServiceClient(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.application_pb_service.ApplicationServiceClient) ExportedTableUpdatesRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.ExportedTableUpdatesRequest) JsLog(io.deephaven.web.client.fu.JsLog) Collectors(java.util.stream.Collectors) HasTableBinding(io.deephaven.web.client.state.HasTableBinding) List(java.util.List) FlightServiceClient(io.deephaven.javascript.proto.dhinternal.arrow.flight.protocol.flight_pb_service.FlightServiceClient) HasLifecycle(io.deephaven.web.client.api.lifecycle.HasLifecycle) Message(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.Message) JsWeakMap(elemental2.core.JsWeakMap) BarrageSubscriptionRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageSubscriptionRequest) ExportedTableUpdateMessage(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.ExportedTableUpdateMessage) Optional(java.util.Optional) TimeTableRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.TimeTableRequest) HandshakeRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.session_pb.HandshakeRequest) Code(io.deephaven.javascript.proto.dhinternal.grpcweb.grpc.Code) Grpc(io.deephaven.javascript.proto.dhinternal.grpcweb.Grpc) BrowserFlightServiceClient(io.deephaven.javascript.proto.dhinternal.arrow.flight.protocol.browserflight_pb_service.BrowserFlightServiceClient) BarrageMessageType(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageMessageType) JsMethod(jsinterop.annotations.JsMethod) HashMap(java.util.HashMap) StateCache(io.deephaven.web.client.api.state.StateCache) HashSet(java.util.HashSet) FetchTableRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.FetchTableRequest) Js(jsinterop.base.Js) FieldNode(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.FieldNode) Charset(java.nio.charset.Charset) Field(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.schema_generated.org.apache.arrow.flatbuf.Field) FetchObjectResponse(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.object_pb.FetchObjectResponse) Long(io.deephaven.javascript.proto.dhinternal.flatbuffers.Long) JsConsumer(io.deephaven.web.shared.fu.JsConsumer) DomGlobal(elemental2.dom.DomGlobal) Schema(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.schema_generated.org.apache.arrow.flatbuf.Schema) TerminationNotificationRequest(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.session_pb.TerminationNotificationRequest) JsDataHandler(io.deephaven.web.client.api.parse.JsDataHandler) BarrageUtils(io.deephaven.web.client.api.barrage.BarrageUtils) FieldInfo(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.application_pb.FieldInfo) BitSet(java.util.BitSet) MessageHeader(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.MessageHeader) BarrageMessageWrapper(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageMessageWrapper) Message(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.Message) ExportedTableUpdateMessage(io.deephaven.javascript.proto.dhinternal.io.deephaven.proto.table_pb.ExportedTableUpdateMessage) RecordBatch(io.deephaven.javascript.proto.dhinternal.arrow.flight.flatbuf.message_generated.org.apache.arrow.flatbuf.RecordBatch) Builder(io.deephaven.javascript.proto.dhinternal.flatbuffers.Builder) ArrayList(java.util.ArrayList) Uint8Array(elemental2.core.Uint8Array) BitSet(java.util.BitSet) ByteBuffer(java.nio.ByteBuffer) BarrageUpdateMetadata(io.deephaven.javascript.proto.dhinternal.io.deephaven.barrage.flatbuf.barrage_generated.io.deephaven.barrage.flatbuf.BarrageUpdateMetadata) FlightData(io.deephaven.javascript.proto.dhinternal.arrow.flight.protocol.flight_pb.FlightData) ClientTableState(io.deephaven.web.client.state.ClientTableState)

Example 5 with ClientTableState

use of io.deephaven.web.client.state.ClientTableState in project deephaven-core by deephaven.

the class RequestBatcher method maybeInsertInterimTable.

private BatchOp maybeInsertInterimTable(BatchOp op, ClientTableState appendTo) {
    op.setAppendTo(appendTo);
    boolean filterChanged = !appendTo.getFilters().equals(op.getFilters());
    if (filterChanged) {
        // whenever filters have changed, we will create one exported table w/ filters and any custom columns.
        // if there are _also_ sorts that have changed, then we'll want to add those on afterwards.
        final List<Sort> appendToSort = appendTo.getSorts();
        final List<Sort> desiredSorts = op.getSorts();
        boolean sortChanged = !appendToSort.equals(desiredSorts);
        if (sortChanged) {
            // create an intermediate state with just custom columns and filters.
            op.setSorts(appendToSort);
            final ClientTableState newAppendTo = insertOp(op, appendTo);
            // get a new "next state" to build, which should only cause sorts to be added.
            final BatchOp newOp = builder.getOp();
            newOp.setSorts(desiredSorts);
            newOp.setFilters(op.getFilters());
            newOp.setCustomColumns(op.getCustomColumns());
            newOp.setFlat(op.isFlat());
            newOp.setAppendTo(newAppendTo);
            JsLog.debug("Adding interim operation to batch", op, " -> ", newOp);
            return newOp;
        }
    }
    return op;
}
Also used : ClientTableState(io.deephaven.web.client.state.ClientTableState) BatchOp(io.deephaven.web.client.api.batch.BatchBuilder.BatchOp)

Aggregations

ClientTableState (io.deephaven.web.client.state.ClientTableState)26 JsMethod (jsinterop.annotations.JsMethod)15 Promise (elemental2.promise.Promise)11 JsLog (io.deephaven.web.client.fu.JsLog)10 CustomEventInit (elemental2.dom.CustomEventInit)9 LazyPromise (io.deephaven.web.client.fu.LazyPromise)9 JsConsumer (io.deephaven.web.shared.fu.JsConsumer)9 JsPropertyMap (jsinterop.base.JsPropertyMap)9 DomGlobal (elemental2.dom.DomGlobal)8 ActiveTableBinding (io.deephaven.web.client.state.ActiveTableBinding)8 JsArray (elemental2.core.JsArray)7 ColumnDefinition (io.deephaven.web.client.api.barrage.def.ColumnDefinition)7 HasLifecycle (io.deephaven.web.client.api.lifecycle.HasLifecycle)7 JsRunnable (io.deephaven.web.shared.fu.JsRunnable)7 JsOptional (jsinterop.annotations.JsOptional)7 Js (jsinterop.base.Js)7 RequestBatcher (io.deephaven.web.client.api.batch.RequestBatcher)6 FilterCondition (io.deephaven.web.client.api.filter.FilterCondition)6 StateCache (io.deephaven.web.client.api.state.StateCache)6 TableViewportSubscription (io.deephaven.web.client.api.subscription.TableViewportSubscription)6