Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add java client TableServiceAsync #4756

Merged
merged 20 commits into from
Nov 7, 2023

Conversation

devinrsmith
Copy link
Member

No description provided.

@devinrsmith devinrsmith added this to the November 2023 milestone Nov 1, 2023
@devinrsmith devinrsmith self-assigned this Nov 1, 2023
@devinrsmith devinrsmith marked this pull request as ready for review November 1, 2023 22:47
interface ExportServiceRequest extends Closeable {
List<Export> exports();

// Note: not providing cancel() or Runnable as return here; we don't really want to cancel a Batch request, we'll
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't trying to cancel the batch maybe be better on the server sometimes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can debate this point once we hook up the on cancel handlers for the server, after the semantics of said cancel is clearly document.


return results;
@Override
public void close() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have the potential for state leak if the user calls close without calling send. Do we need to clean those up? What about on errors?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I've added some new logic to handle the case where the user does not call send. After sent, any errors are the handled by respective io.deephaven.client.impl.ExportRequest.listener.

@Override
public TableHandleManager serial() {
return serialManager;
protected TableServices delegate() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the pattern is we construct a whole bunch of state, and then throw it away...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. The internal state is needed even for a single query - there may be shared sub-DAGs that we don't want to export multiple times in a single Batch request. One might argue "we should re-implement all of this logic, only keeping the state/Map alive for the duration of the execute method", but re-working as such would add additional maintenance burdens for the sake of saving the construction of a extra object, which is not even close to worth it IMO.

interface TableHandleFuture extends Future<TableHandle> {

/**
* Waits if necessary for the computation to complete, and then retrieves its result. If an
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This JavaDoc is trying to describe a somewhat complex set of branching logic, but the actual branches are hard to understand from reading the doc.

}
}

static <T> void cancelOrConsume(Iterable<? extends Future<T>> futures, BiConsumer<T, ExecutionException> consumer,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class could generally use some JavaDoc, but cancelOrConsume is the weirdest. Maybe a "tri consumer" is more appropriate, for CancellationExceptions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FutureConsumer works nicely.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some javadoc to cancelOrConsume b/c it's easy, but I don't know how to easily document getOrCancel without getting into the weeds of the exact implementation.

@@ -224,7 +261,7 @@ class State {
State(TableSpec table, int exportId) {
this.table = Objects.requireNonNull(table);
this.exportId = exportId;
this.children = new LinkedHashSet<>();
this.children = new CopyOnWriteArraySet<>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand we want this to avoid CME's on remove during an iteration. Can we build a list to remove and do a removeAll instead? I'm worried about adding COW data structures with user-facing adds.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I more thoroughly traced exactly the part that was causing concurrent mod, and it was actually the mitigation; now that the Batch / ETCR race has been fixed, I can get rid of the mitigation and revert this change.

@devinrsmith devinrsmith merged commit 7a4119f into deephaven:main Nov 7, 2023
10 checks passed
@devinrsmith devinrsmith deleted the nightly/table-service-async branch November 7, 2023 16:22
@github-actions github-actions bot locked and limited conversation to collaborators Nov 7, 2023
@deephaven-internal
Copy link
Contributor

Labels indicate documentation is required. Issues for documentation have been opened:

How-to: https://github.com/deephaven/deephaven.io/issues/3399
Reference: https://github.com/deephaven/deephaven.io/issues/3400

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants