-
Notifications
You must be signed in to change notification settings - Fork 80
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
fix: Clean up how objects are managed when they are fetched #4909
Conversation
- Previously, exported objects were not handling their fetched objects correctly - Tables were not using copies, only widgets were - The parent ticket was not being released in many cases (TreeTable, PartitonedTable, PandasTable) - Refactored so exported objects always follow the same path - Just call connection.getObject, which always creates a new ticket for the object - Still need to close the widget so it closes the exported objects - Test by adding debug logging for SessionState: ```py import jpy logger = jpy.get_type('org.slf4j.LoggerFactory').getLogger('io.deephaven.server.session.SessionState') jpy.cast(logger, jpy.get_type('ch.qos.logback.classic.Logger')).setLevel(jpy.get_type('ch.qos.logback.classic.Level').DEBUG) ```
- Now it doesn't need to do the extra round trip
- Have the exported object "own" the ticket until it is taken from it
- Clean up memory leak in JsPartitionedTable, JsFigure, PandasTable with widgets not being closed after being used - Add a `takeTicket` method to JsWidgetExportedObject to make it clear when ownership of the ticket has been passed on - Close exported objects that are still owned when closing a widget - Tested using the steps and scripts provided in the ticket, as well as testing with creating some tables and opening/closing them in the UI - Fixes deephaven#4903
web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java
Outdated
Show resolved
Hide resolved
web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java
Outdated
Show resolved
Hide resolved
web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java
Outdated
Show resolved
Hide resolved
web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java
Outdated
Show resolved
Hide resolved
web/client-api/src/main/java/io/deephaven/web/client/api/tree/JsTreeTable.java
Outdated
Show resolved
Hide resolved
web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidgetExportedObject.java
Outdated
Show resolved
Hide resolved
takeOwnership = false; | ||
} | ||
if (takeOwnership) { | ||
return this.connection.getObject(takeTicket()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this means that raced calls to fetch(true)
and fetch(false)
are going to intermittently fail - probably need some clearer docs on this and other general usage of ownership.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was debating just having a separate method take
instead of making it a boolean.
Really you should only be calling one or the other (true
or false
) depending on how you're managing the object, I wouldn't expect you'd want to call both.
In any case, I can add a verifyIsOwner()
here in the false
case, and throw if it's been called after a fetch(false)
so it reduces a race that way, but you could still race fetch(false)
then fetch(true)
I suppose.
} | ||
return this.connection.getObject( | ||
new JsVariableDefinition(ticket.getType(), null, ticket.getTicket().getTicket_asB64(), null)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised this works - VariableDefinition is meant for scope tickets...
Will think on it more, but I think I'd prefer we decompose this (or provide an interface and second impl) to let this be reexported-and-fetched.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, that was already there. Looks like I added this back when implementing JsWidget: #1888 (comment)
I may have misinterpreted that comment then.
Should be able to refactor the WorkerConnection#getObject
methods; the only part of the JsVariableDefinition
that is actually used is the type
and the id
used in exportScopeTicket
web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java
Outdated
Show resolved
Hide resolved
web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java
Outdated
Show resolved
Hide resolved
…rConnection.java Co-authored-by: Colin Alworth <colin@vertispan.com>
Co-authored-by: Colin Alworth <colin@vertispan.com>
- Can release the ticket of a widget automatically if the server closes the object - no way to reconnect (currently) - Remove unnecessary closes
web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidget.java
Show resolved
Hide resolved
web/client-api/src/main/java/io/deephaven/web/client/api/widget/JsWidget.java
Outdated
Show resolved
Hide resolved
web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java
Outdated
Show resolved
Hide resolved
web/client-api/src/main/java/io/deephaven/web/client/api/WorkerConnection.java
Outdated
Show resolved
Hide resolved
* @param refetch Whether to refetch the widget before resolving or not | ||
* @return Promise of the widget | ||
*/ | ||
public Promise<JsWidget> getWidget(JsVariableDefinition varDef, boolean refetch) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of "refetch" could we use something like "export" or "re-export"? Most of the time "Fetch" means to get the object from the server (usually by name), but this isn't doing that again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The refetch
in this case is triggering widget.refetch()
, which was already named... but essentially is restarting the stream and fetching the data. I think the reexport
name probably doesn't fit here either, and refetch
makes more sense (or JsWidget.refetch
should be renamed?). Thoughts?
…rConnection.java Co-authored-by: Colin Alworth <colin@vertispan.com>
…t/JsWidget.java Co-authored-by: Colin Alworth <colin@vertispan.com>
- Made many methods private instead of public - Renamed methods to `getExported*` to make it clear they are for server-side exports - Changed default method of `JsWidgetExportedObject.fetch` so this is not a breaking change
Rollups are screwed up, need to fix... |
- JsTreeTable was using the ticket from the widget directly, which doesn't work now if the widget releases it's ticket when the stream disconnects (fetch-only widgets) - Need to export the table as an exportedObject so we don't release it entirely - Will need Colin to review, this seems a little strange.
@niloc132 So the issue now with releasing the widget ticket when the stream ends (as suggested in our previous discussion for fetch-only widgets) actually breaks JsTreeTable implementation, as it's using the ticket right from the widget for the hierarchical table?? deephaven-core/web/client-api/src/main/java/io/deephaven/web/client/api/tree/JsTreeTable.java Line 512 in 1607606
So I changed HierarchicalTableTypePlugin to export a reference to the HierarchicalTable as an exported object... but I think JsPartitionedTable still has a problem... they're not expecting the widget ticket to be released after the widget has been fetched, which is at odds with what we're doing with Pandas (I'm actually not sure where the Pandas plugin is/how that works?). I favour what I had previously, where the consumer needs to explicitly close the widget when they're done with it to release the ticket, rather than implicitly releasing the ticket when the stream ends... thoughts? |
Closed in favour of #4939 |
takeTicket
method to JsWidgetExportedObject to make it clear when ownership of the ticket has been passed on