fix: lake: properly prepend job log in ensureJob (#6291)

This PR ensures the the log error position is properly preserved when
prepending stray log entries to the job log. It also adds comparison
support for `Log.Pos`.
This commit is contained in:
Mac Malone 2024-12-02 18:43:12 -05:00 committed by GitHub
parent d9d54c1f99
commit f6bc6b2eb1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 22 additions and 5 deletions

View file

@ -93,10 +93,12 @@ def ensureJob (x : FetchM (Job α))
let iniPos := log.endPos
match (← (withLoggedIO x) fetch stack ctx log store) with
| (.ok job log, store) =>
let (log, jobLog) := log.split iniPos
let job := if jobLog.isEmpty then job else job.mapResult (sync := true)
(·.modifyState (.modifyLog (jobLog ++ ·)))
return (.ok job log, store)
if iniPos < log.endPos then
let (log, jobLog) := log.split iniPos
let job := job.mapResult (sync := true) (·.prependLog jobLog)
return (.ok job log, store)
else
return (.ok job log, store)
| (.error _ log, store) =>
let (log, jobLog) := log.split iniPos
return (.ok (.error jobLog) log, store)

View file

@ -64,6 +64,12 @@ def JobState.merge (a b : JobState) : JobState where
/-- The result of a Lake job. -/
abbrev JobResult α := EResult Log.Pos JobState α
/-- Add log entries to the beginning of the job's log. -/
def JobResult.prependLog (log : Log) (self : JobResult α) : JobResult α :=
match self with
| .ok a s => .ok a <| s.modifyLog (log ++ ·)
| .error e s => .error ⟨log.size + e.val⟩ <| s.modifyLog (log ++ ·)
/-- The `Task` of a Lake job. -/
abbrev JobTask α := BaseIOTask (JobResult α)

View file

@ -262,9 +262,18 @@ instance : FromJson Log := ⟨(Log.mk <$> fromJson? ·)⟩
/-- A position in a `Log` (i.e., an array index). Can be past the log's end. -/
structure Log.Pos where
val : Nat
deriving Inhabited
deriving Inhabited, DecidableEq
instance : OfNat Log.Pos (nat_lit 0) := ⟨⟨0⟩⟩
instance : Ord Log.Pos := ⟨(compare ·.val ·.val)⟩
instance : LT Log.Pos := ⟨(·.val < ·.val)⟩
instance : DecidableRel (LT.lt (α := Log.Pos)) :=
inferInstanceAs (DecidableRel (α := Log.Pos) (·.val < ·.val))
instance : LE Log.Pos := ⟨(·.val ≤ ·.val)⟩
instance : DecidableRel (LE.le (α := Log.Pos)) :=
inferInstanceAs (DecidableRel (α := Log.Pos) (·.val ≤ ·.val))
instance : Min Log.Pos := minOfLe
instance : Max Log.Pos := maxOfLe
namespace Log