-
Notifications
You must be signed in to change notification settings - Fork 81
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
ObjectType and Plugins #1787
ObjectType and Plugins #1787
Conversation
To try out locally, modify dockerfile docker/server/src/main/docker/Dockerfile and then prepareCompose: # To test out the deephaven-plugin-matplotlib, uncomment the following:
#RUN set -eux; \
# python3 -m pip install -q --no-cache-dir \
# importlib-metadata \
# https://github.com/deephaven/deephaven-plugin-matplotlib/releases/download/v0.0.1.dev1/deephaven_plugin_matplotlib-0.0.1.dev1-py3-none-any.whl Start server, run script: import matplotlib.pyplot as plt
x = [0, 2, 4, 6]
y = [1, 3, 4, 8]
plt.plot(x, y)
plt.xlabel('x values')
plt.ylabel('y values')
plt.title('plotted x and y values')
plt.legend(['line 1'])
m_figure = plt.gcf() Client tests: ./gradlew java-client-session-examples:installDist
./java-client/session-examples/build/install/java-client-session-examples/bin/fetch-object --variable m_figure > /tmp/m_figure.png
./java-client/session-examples/build/install/java-client-session-examples/bin/subscribe-fields |
engine/table/src/main/java/io/deephaven/engine/util/PythonDeephavenSession.java
Outdated
Show resolved
Hide resolved
|
||
private final PyDictWrapper dict; | ||
|
||
public PythonSnapshot(PyDictWrapper dict) { |
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.
aren't these snapshot types just wrappers around the getVariables/getVariable calls? why does each lang need to reimplement the diff?
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 old version was very inefficient (getVariables is very inefficient for python). In general, I think our ScriptSession interface as a top-level programmatic object leaves a lot to be desired, esp wrt python. Pushing some of the compute changes logic down into python allows us to avoid crossing the JNI boundary as much. I'd like to take it further at some point, as I think more logic can/should be moved into python.
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.
Okay, I'll let this be deferred, but while I also dislike the current AbstractScriptSession/QueryScope abstraction/relationship, I dont think we're tearing out enough in this patch, or designing (i.e. with review) the new approach/api being put here.
If it is a good idea to remove, I'd rather do it in a complete way.
plugin/figure/src/main/java/io/deephaven/figure/FigureWidgetTranslator.java
Outdated
Show resolved
Hide resolved
import dagger.Module; | ||
|
||
@Module(includes = {ObjectTypesModule.class}) | ||
public interface PluginModule { |
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.
does this serve a purpose on its own? it seems like it just pulls in the plugin.ObjectTypesModule?
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've got a follow up PR for an application plugin; instead of refactoring the structure in the application plugin, I'm providing the follow-up structure for it here.
return Optional.empty(); | ||
} | ||
|
||
public synchronized void register(ObjectType type) { |
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.
is there no public API to programmatically register a new ObjectType? This class is package-protected, and ObjectTypeLookup doesnt declare this method
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.
Right now, I'm thinking that it's only via plugin mechanisms. We could expose the register
, but I think it has some non-obvious implications for the script session (and application fields) changeListener
wrt "displayble" types.
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 definitely imagining a use case where a java/groovy user would want to iterate without knocking over the server with every change - just keep calling register (and a matching unregister?) as you tweak the class definition in the console, fetch from the client to work on it. Probably matters less locally, but maybe more on a server deployment.
This might just be in my head - but with such a flexible mechanism (and already threadsafe etc), it seems like a shame to keep it from power users.
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.
punting for now #1809
server/src/main/java/io/deephaven/server/plugin/ObjectTypesModule.java
Outdated
Show resolved
Hide resolved
server/src/main/java/io/deephaven/server/plugin/ObjectTypesModule.java
Outdated
Show resolved
Hide resolved
engine/table/src/main/java/io/deephaven/engine/util/AbstractScriptSession.java
Show resolved
Hide resolved
engine/table/src/main/java/io/deephaven/engine/util/GroovyDeephavenSession.java
Outdated
Show resolved
Hide resolved
engine/table/src/main/java/io/deephaven/engine/util/NoLanguageDeephavenSession.java
Outdated
Show resolved
Hide resolved
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) | ||
return true; | ||
if (o == null || getClass() != o.getClass()) | ||
return false; | ||
ObjectTypeClassBase<?> that = (ObjectTypeClassBase<?>) o; | ||
if (!name.equals(that.name)) | ||
return false; | ||
return clazz.equals(that.clazz); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
int result = name.hashCode(); | ||
result = 31 * result + clazz.hashCode(); | ||
return result; | ||
} |
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.
These seem unnecessary to define.
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.
If ObjectTypeClassBase instances can handle subtypes (as they seem to be able to do, except in the actual registry impl), this could be necessary... something to this effect anyway, traverse the already assembled instances to figure out which one applies to a given object (imagine registering, for example, Object, Number, and Double, make sure String gets the Object instance, Long gets the Number instance, etc)
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 don't mean for it to handle subtypes ATM. We can update the impl in the future if necessary. I think Ryan is correct, will remove equals/hashcode atm.
proto/proto-backplane-grpc/src/main/proto/deephaven/proto/application.proto
Outdated
Show resolved
Hide resolved
Sorry I ran out of time to write a summary, and wanted to get these earlier thoughts to you. My main worry is that there is too much implementation and not enough API - there are roughly two APIs here, a gRPC/pb one for clients, and a java/python api to declare/instantiate/register the handlers. I mostly would like some improvement at this point on the gRPC/pb side, as I think that is the part we've thought out the most from a consumption perspective the most (and the case where we most want to avoid more than one way to do something). My main points to stick to:
Let's try to chat a bit tomorrow, I'll generate the gwt bindings so that the client refactor can get an update and we can give it a shakedown on figures, expose matlibplot to js? |
cc1a9c9
to
33cf3d2
Compare
server/src/main/java/io/deephaven/server/session/SessionState.java
Outdated
Show resolved
Hide resolved
@Singleton | ||
public final class ObjectTypes implements ObjectTypeLookup, ObjectTypeRegistration { | ||
|
||
private static final Set<String> RESERVED_TYPE_NAMES_LOWERCASE = Set.of("table", "tablemap", "treetable", ""); |
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.
should we reserve figure
in some way? not sure of the mechanics of how this works, if it makes any more sense to reserve tablemap than figure...
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 more inclined to want to namespace Figure as something like io.deephaven.Figure
(doesn't have to be the full Figure class, but something that could be stable and survive implementation refactorings). As it is now, if somebody else tries to install a "Figure" object type, we'll blow up at startup.
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.
Should verify that "tablemap" is going to be a thing (with that word) - but while i agree that our "table" should win over other tables, i'm not sure why our tablemap or treetable would be any more essential than our figures when it comes to serialization to a client.
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.
Assuming we can revisit this later.
Fixes #1766