blob: 9e637a0482c9c8c1f4f9ead037d2a15747568cd8 [file]
/-
Copyright (c) 2020 Wojciech Nawrocki. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Wojciech Nawrocki, Marc Huisinga
-/
import Lean.Server.Utils
import Lean.Server.Snapshots
import Lean.Server.AsyncList
import Lean.Server.Rpc.Basic
namespace Lean.Server.FileWorker
open Snapshots
open IO
def logSnapContent (s : Snapshot) (text : FileMap) : IO Unit :=
IO.eprintln s!"[{s.beginPos}, {s.endPos}]: ```\n{text.source.extract s.beginPos (s.endPos - ⟨1⟩)}\n```"
inductive ElabTaskError where
| aborted
| ioError (e : IO.Error)
instance : Coe IO.Error ElabTaskError :=
⟨ElabTaskError.ioError⟩
instance : MonadLift IO (EIO ElabTaskError) where
monadLift act := act.toEIO (↑ ·)
structure CancelToken where
ref : IO.Ref Bool
namespace CancelToken
def new : IO CancelToken :=
CancelToken.mk <$> IO.mkRef false
def check [MonadExceptOf ElabTaskError m] [MonadLiftT (ST RealWorld) m] [Monad m] (tk : CancelToken) : m Unit := do
let c ← tk.ref.get
if c then
throw ElabTaskError.aborted
def set (tk : CancelToken) : IO Unit :=
tk.ref.set true
end CancelToken
/-- A document editable in the sense that we track the environment
and parser state after each command so that edits can be applied
without recompiling code appearing earlier in the file. -/
structure EditableDocument where
meta : DocumentMeta
/-- State snapshots after header and each command. -/
cmdSnaps : AsyncList ElabTaskError Snapshot
cancelTk : CancelToken
namespace EditableDocument
end EditableDocument
structure RpcSession where
objects : RpcObjectStore
/-- The `IO.monoMsNow` time when the session expires. See `$/lean/rpc/keepAlive`. -/
expireTime : Nat
namespace RpcSession
def keepAliveTimeMs : Nat :=
30000
def new : IO (UInt64 × RpcSession) := do
/- We generate a random ID to ensure that session IDs do not repeat across re-initializations
and worker restarts. Otherwise, the client may attempt to use outdated references. -/
let newId ← ByteArray.toUInt64LE! <$> IO.getRandomBytes 8
let newSesh := {
objects := {}
expireTime := (← IO.monoMsNow) + keepAliveTimeMs
}
return (newId, newSesh)
def keptAlive (monoMsNow : Nat) (s : RpcSession) : RpcSession :=
{ s with expireTime := monoMsNow + keepAliveTimeMs }
def hasExpired (s : RpcSession) : IO Bool :=
return s.expireTime ≤ (← IO.monoMsNow)
end RpcSession
end Lean.Server.FileWorker