penrose / penrose

Create beautiful diagrams just by typing notation in plain text.
https://penrose.cs.cmu.edu
MIT License
7.45k stars 339 forks source link

RESTful API to the backend #212

Closed wodeni closed 5 years ago

wodeni commented 5 years ago

Overview

For each client, the backend server is single-threaded and acts as a state machine. However, we would like to make concurrent requests on both the language and graphics sides (e.g. optimizing a diagram while editing Substance program). Therefore, we propose to rewrite the backend server to be stateless and move the server logic for a single client to the frontend. Instead of keeping all states of the client in the backend, each client will store its state in the frontend and make various requests to the backend server with its state as the payload. The frontend is responsible to handle packets in a way akin to the existing state machine:

image

Potential benefits of this approach include:

In this document, we will:

Haskell backend API

We specify the backend API by going through all functions used by the existing server module and any other ad hoc computation involved:

Optimizer

Parsers

Other computation

Frontend state machine spec

TODO: discuss with @maxkrieger

Changes needed to the existing system

TODO: discuss with @hypotext and @maxkrieger

kai-qu commented 5 years ago

Looks great so far, thanks for writing this up!

I think we should work out and agree on the type of State in the frontend soon, because that influences the whole design.

For the other computations: I'd say the logic about UI actions should go in the frontend so it can update as fast as possible without making a roundtrip to the server (dragUpdate and dragShape). The other functions that involve changing the translation would likely be better as functions in the backend API (so, updateShapes and resample).

One question: Will multiple clients ever need to interact and share state?

Let me know when/how you want to move this forward. If you are heading out on May 7 then we should schedule a meeting before then.

maxkrieger commented 5 years ago

Will multiple clients ever need to interact and share state?

If they do, I don't think it should happen at the Penrose "layer" of the stack. I.e. if you're referring to realtime collaboration, we should handle that behavior at the same higher-level layer that'll handle the meta-activities like collaborative editors, storing serialized states for sharing, etc. I'm eyeing playing with an Elixir/Phoenix stack (or a hacky Firebase one to start) early on this summer for that layer of the platform.

wodeni commented 5 years ago

Now that State is serializable. @maxkrieger and I will start rearchitecting the system. The first task we agreed on is to write a RESTful version of react-renderer with (1) the WS connection, (2) compressed JSON packets of State, and (3) the following API calls to the backend:

compileTrio 
    :: String -- ^ a Substance program
    -> String -- ^ a Style program
    -> String -- ^ an Element program
    -> Either State CompilerError  -- ^ an initial state generated by the backend (errors will be included in the state somehow)

step 
    :: State  -- ^ the initial state
    -> Int    -- ^ the number of steps n for the optimizer to take
    -> State  -- ^ the resulting state after the optimizer takes n steps

stepUntilConvergence 
    :: State                       -- ^ the initial state
    -> Either State OptimizerError -- ^ the converged state or optimizer errors
wodeni commented 5 years ago

236 addresses this issue. Closing now.