Skip to content

Commit

Permalink
address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
V-FEXrt committed Sep 5, 2024
1 parent bbfaf25 commit 46c4000
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 39 deletions.
55 changes: 33 additions & 22 deletions share/wake/lib/system/io.wake
Original file line number Diff line number Diff line change
Expand Up @@ -129,32 +129,43 @@ export def read (path: Path): Result String Error =
Pass body -> Pass body
Fail f -> Fail (makeError f)

target writeImp inputs mode path content =
# TODO: move this runner out of writeImp and don't directly depent on the parameters passed in to writeImp
# See mkdirRunner for example of proper implementation
def writeRunner =
def primWrite (mode: Integer) (path: String) (content: String): Result String String =
(\_ \_ \_ prim "write") mode path content
# writeRunner: A runner that processes special write jobs
#
# Allows for calls to the write prim to be tracked in the database as any other job.
# Ideally content would be part of RunnerInputCmd however this gets tracked exactly in the database
# which means all writes would cost 2x the total amount.
def writeRunner (content: String) =
def primWrite (mode: Integer) (path: String) (content: String): Result String String =
(\_ \_ \_ prim "write") mode path content

def run (job: Job) ((RunnerInput _ _ vis _ _ _ _ _ predict _): RunnerInput): Result RunnerOutput Error =
# Insert the <write> job into the database
def _ = primJobVirtual job "" "" predict
def run (job: Job) ((RunnerInput _ cmd vis _ _ _ _ _ predict _): RunnerInput): Result RunnerOutput Error =
# Command must be ("<write>", "-m", "{string mode}", "{string path}", Nil)
require "<write>", "-m", smode, path, Nil = cmd
else panic "writeImp violated command-line contract"

# Insert the <write> job into the database
def _ = primJobVirtual job "" "" predict

# Wait for the virtual job to complete
require Pass reality = job.getJobReality
# Wait for the virtual job to complete
require Pass reality = job.getJobReality

# Actually trigger the effects required by the job
def mode =
int smode
| getOrElse 0x200

# Actually trigger the effects required by the job
require True = mode >= 0 && mode <= 0x1ff
else failWithError "write {path}: Invalid mode ({strOctal mode})"
require True = mode >= 0 && mode <= 0x1ff
else failWithError "write {path}: Invalid mode ({strOctal mode})"

match (primWrite mode path content)
Fail f -> failWithError f
Pass path ->
RunnerOutput (vis | map getPathName) (path,) reality
| Pass
match (primWrite mode path content)
Fail f -> failWithError f
Pass path ->
RunnerOutput (vis | map getPathName) (path,) reality
| Pass

makeRunner "write" run
makeRunner "write" run

target writeImp inputs mode path content =
# There are a couple likely bad paths that we don't want the user writing to
# so we give good error messages for these cases
require False = path ==* ""
Expand Down Expand Up @@ -184,11 +195,11 @@ target writeImp inputs mode path content =

# If all those checks pass we go ahead and perform the write. The write will
# overwrite single files but it will not overwrite a whole directory with a file.
makeExecPlan ("<write>", "0{strOctal mode}", path, Nil) inputs
makeExecPlan ("<write>", "-m", "0{strOctal mode}", path, Nil) inputs
| setPlanLabel "write: {path} 0{strOctal mode}"
| setPlanOnce False
| setPlanEnvironment Nil
| runJobWith writeRunner
| runJobWith (writeRunner content)
| setJobInspectVisibilityHidden
| getJobOutput

Expand Down
21 changes: 16 additions & 5 deletions share/wake/lib/system/job.wake
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ export tuple JobKey =
export isatty: Integer

# Create/reserve a job handle, parameters aren't necessarily finalized
export def primJobCreate (label: String) ((JobKey dir stdin env cmd signature visible isatty): JobKey) (keep: Integer) (echo: String) (stdout: String) (stderr: String): Job =
export def primJobCreate (label: String) (jobKey: JobKey) (keep: Integer) (echo: String) (stdout: String) (stderr: String): Job =
def JobKey dir stdin env cmd signature visible isatty = jobKey

(\_ \_ \_ \_ \_ \_ \_ \_ \_ \_ \_ \_ prim "job_create")
label
dir
Expand All @@ -41,7 +43,9 @@ export def primJobCreate (label: String) ((JobKey dir stdin env cmd signature vi
isatty

# Imediatly complete a job with the provided ouputs without launching a process
export def primJobVirtual (job: Job) (stdout: String) (stderr: String) ((Usage status runtime cputime membytes ibytes obytes): Usage): Unit =
export def primJobVirtual (job: Job) (stdout: String) (stderr: String) (usage: Usage): Unit =
def Usage status runtime cputime membytes ibytes obytes = usage

(\_ \_ \_ \_ \_ \_ \_ \_ \_ prim "job_virtual")
job
stdout
Expand All @@ -54,7 +58,10 @@ export def primJobVirtual (job: Job) (stdout: String) (stderr: String) ((Usage s
obytes

# Launch the job via a child process. Values such as command or environment can be freely changed from the initial reservation.
export def primJobLaunch (job: Job) ((JobKey dir stdin env cmd signature visible isatty): JobKey) ((Usage status runtime cputime membytes ibytes obytes): Usage): Unit =
export def primJobLaunch (job: Job) (jobKey: JobKey) (usage: Usage): Unit =
def JobKey dir stdin env cmd _signature _visible isatty = jobKey
def Usage status runtime cputime membytes ibytes obytes = usage

(\_ \_ \_ \_ \_ \_ \_ \_ \_ \_ \_ \_ prim "job_launch")
job
dir
Expand All @@ -78,7 +85,9 @@ export def primJobFailFinish (job: Job) (error: Error): Unit =
(\_ \_ prim "job_fail_finish") job error

# Complete a job successfully by providing to the runtime the inputs/outputs/usage of the job
export def primJobFinish (job: Job) (inputs: String) (outputs: String) (all_outputs: String) ((Usage status runtime cputime membytes ibytes obytes): Usage): Unit =
export def primJobFinish (job: Job) (inputs: String) (outputs: String) (all_outputs: String) (usage: Usage): Unit =
def Usage status runtime cputime membytes ibytes obytes = usage

(\_ \_ \_ \_ \_ \_ \_ \_ \_ \_ prim "job_finish")
job
inputs
Expand All @@ -92,7 +101,9 @@ export def primJobFinish (job: Job) (inputs: String) (outputs: String) (all_outp
obytes

# Look up a job in the local database. Returns a completed Job handle with outputs already resolved if it is already cached
export def primJobCache ((JobKey dir stdin env cmd signature visible isatty): JobKey): Pair (List Job) (List (Pair String String)) =
export def primJobCache (jobKey: JobKey): Pair (List Job) (List (Pair String String)) =
def JobKey dir stdin env cmd signature visible isatty = jobKey

(\_ \_ \_ \_ \_ \_ \_ prim "job_cache") dir stdin env cmd signature visible isatty

# Creates a hash of 5 elements
Expand Down
28 changes: 16 additions & 12 deletions share/wake/lib/system/runner.wake
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,15 @@ export tuple Runner =

# makeRunner: Hides some of the boiler plate required to create a runner
#
# This function requires very advanced wake expierence and should be used with the greatest amount of caution.
# Callers must ensure at the very least than run calls primJobLaunch and one of the many job "wait" functions.
# Runners should not wrap other runners instead they should precisely do what they need to complete their task.
# This function requires very advanced wake experience and should be used with the greatest amount
# of caution. Callers must ensure at the very least that `run` calls primJobLaunch and one of the
# many job "wait" functions. Historically runners allowed dispatching to an arbirary "base" or
# "inner" runner. This significantly complicated the system and led to very unexpected interactions.
# It is recomennded that runners don't accept an "inner" runner and instead directly call the job
# primatives. If wrapping is unavoidable then the specific runner being wrapped should be named
# instead of accepting an arbitrary runner parameter.
#
# localRunner is a good reference implementation.
# localRunner is a good reference implementation of the run function.
export def makeRunner (name: String) (run: Job => RunnerInput => Result RunnerOutput Error): Runner =
def do job maybeInput = match maybeInput
Fail e ->
Expand All @@ -84,9 +88,8 @@ export def localRunner: Runner =
def jobKey = JobKey dir stdin env.implode cmd.implode 0 "" isatty.booleanToInteger
def _ = primJobLaunch job jobKey predict

job
| getJobReality
|< (\reality RunnerOutput (vis | map getPathName) Nil reality)
job.getJobReality
|< RunnerOutput (vis | map getPathName) Nil

makeRunner "local" run

Expand All @@ -97,14 +100,15 @@ export def virtualRunner: Runner =
def run (job: Job) ((RunnerInput _ _ vis _ _ _ _ _ predict _): RunnerInput): Result RunnerOutput Error =
def _ = primJobVirtual job "" "" predict

job
| getJobReality
|< (\reality RunnerOutput (vis | map getPathName) Nil reality)
job.getJobReality
|< RunnerOutput (vis | map getPathName) Nil

makeRunner "virtual" run

# depreMakeRunner: Deprecated. Do not use
export def depreMakeRunner name pre post (Runner _ run) =
# wrapRunner: Deprecated. Do not use this function.
#
# It will be deleted in the next release. See makeRunner for migration
export def wrapRunner name pre post (Runner _ run) =
def doit job preInput = match (pre preInput)
Pair runInput state ->
def runOutput = run job runInput
Expand Down

0 comments on commit 46c4000

Please sign in to comment.