replikativ / datahike

A fast, immutable, distributed & compositional Datalog engine for everyone.
https://datahike.io
Eclipse Public License 1.0
1.62k stars 95 forks source link

Enhance: Introduce global address space and HTTP client/server. #639

Closed whilo closed 10 months ago

whilo commented 1 year ago

This PR integrates datahike-server and provides a HTTP client. It provides a serialization mapping of all Datahike primitives (connections, dbs, ...) and a unified API that can be exported. CLI/pod and Java API/libdtahike still need to be derived from the generalized API specification.

The main work of the PR is pulling out the API specification into a map in api_specification.clj and then deriving the server, client and api namespace from it. Supporting implemenations for the specification are now in api_impl.clj. The rest of the http/server.clj code is effectively reflecting what was in datahike-server before, the main difference is that all building blocks can now be called as functions, i.e. routes with create-routes and don't implicitly depend on runtime singletons such as the mounted config anymore. This allows users to expose the routes in their own ring-compatible server setup without having to buy into jetty.

Both the HTTP server and client use datahike.readers and datahike.transit to embed Datahike primitives (dbs, connections etc.) depending on the content-type. I will re-add JSON with another PR. datahike.remote provides remote pointers to connections and db types, so that the HTTP client can work exactly like datahike.api, but it is only pointing to remote objects, not directly implementing connections or datahike databases. Beyond that I have removed some redundant transact functions in datahike.core that double swapped the nested atom of a connection unnecessarily.

TimoKramer commented 11 months ago

Testing with the server in the repl I am getting an error:

; eval (word): conn
; (err) Error printing return value (IllegalArgumentException) at clojure.lang.MultiFn/findAndCacheBestMethod (MultiFn.java:179).
; (err) Multiple methods in multimethod 'simple-dispatch' match dispatch value: class datahike.remote.RemoteConnection -> interface clojure.lang.IPersistentMap and interface clojure.lang.IDeref, and neither is preferred

when running this:

(comment
  (def client-config {:backend :datahike-server
                               :url    "http://localhost:3000"
                               :token  "securerandompassword"
                               :format :transit})
   (def new-config (api/create-database {:schema-flexibility :read
                                                                 :remote-peer        client-config}))
   (def conn (api/connect new-config))     ■ Unused public var 'datahike.test.http.server-test/conn'

Any idea why?

whilo commented 11 months ago

Testing with the server in the repl I am getting an error:

; eval (word): conn
; (err) Error printing return value (IllegalArgumentException) at clojure.lang.MultiFn/findAndCacheBestMethod (MultiFn.java:179).
; (err) Multiple methods in multimethod 'simple-dispatch' match dispatch value: class datahike.remote.RemoteConnection -> interface clojure.lang.IPersistentMap and interface clojure.lang.IDeref, and neither is preferred

when running this:

(comment
  (def client-config {:backend :datahike-server
                               :url    "http://localhost:3000"
                               :token  "securerandompassword"
                               :format :transit})
   (def new-config (api/create-database {:schema-flexibility :read
                                                                 :remote-peer        client-config}))
   (def conn (api/connect new-config))     ■ Unused public var 'datahike.test.http.server-test/conn'

Any idea why?

I found this issue and added the preference code https://github.com/thi-ng/color/issues/10.

TimoKramer commented 11 months ago

Found two issues:

  1. When opening the swagger site and running a command there is a huge stack trace returned. This should be resolved. Apart from that and the documentation that I really would love to see I think this is a really good solution.
  2. When transacting bad data with write-schema I am getting this back with the client:
    #error {
    :cause "Don't know how to create ISeq from: jdk.internal.net.http.ResponseSubscribers$HttpResponseInputStream"
    :via
    [{:type java.lang.IllegalArgumentException
    :message "Don't know how to create ISeq from: jdk.internal.net.http.ResponseSubscribers$HttpResponseInputStream"
    :at [clojure.lang.RT seqFrom "RT.java" 557]}]
whilo commented 11 months ago

Found two issues:

1. When opening the swagger site and running a command there is a huge stack trace returned. This should be resolved. Apart from that and the documentation that I really would love to see I think this is a really good solution.

2. When transacting bad data with write-schema I am getting this back with the client:
#error {
 :cause "Don't know how to create ISeq from: jdk.internal.net.http.ResponseSubscribers$HttpResponseInputStream"
 :via
 [{:type java.lang.IllegalArgumentException
   :message "Don't know how to create ISeq from: jdk.internal.net.http.ResponseSubscribers$HttpResponseInputStream"
   :at [clojure.lang.RT seqFrom "RT.java" 557]}]

This problem is probably because we pass all arguments in a vector, this is explained at the very top. Did you pass the arguments like that?

TimoKramer commented 11 months ago

I can not review right now since I am on vacation and did not bring my laptop. I hope you can wait until beginning of October. But so far it looks good!