Class StarlarkScript

java.lang.Object
org.microproxy.starlark.StarlarkScript

public final class StarlarkScript extends Object
A compiled Starlark file whose top-level statements have run. Its globals are frozen, so one script is safely shared by every connection: each call gets its own StarlarkThread, and functions cannot change global state. Calls are bounded by a step count, a wall-clock timeout and an allocation budget (StarlarkScript.Limits).

Each call is measured: its interpreter steps, about how many bytes of values it created (StarlarkThread.getAllocatedBytes(), an estimate of what was made rather than of what stayed in memory) and its time. With metrics they go to hooks.starlark.<script>.<hook>.*, tagged with the script's name and the hook; they add up per exchange in FlowContext.scriptStats(); a ScriptCallObserver sees each call; and a call for an exchange whose trace is sampled gets a span of its own, a child of the exchange's (starlark <hook>, see ScriptSpans).

A script may load() modules of the standard library ported from starlarky (Stdlib), e.g. load("@stdlib//urllib/parse", "parse"). Such a script runs with Python's string semantics (Stdlib.withPythonStrings(org.microproxy.thirdparty.starlark.eval.StarlarkSemantics)), which the library relies on; a script without load statements runs exactly as before.

  • Method Details

    • statsName

      public String statsName()
      The name this script's stats are tagged with (microproxy_script): its file name without .star, or the one given to withStatsName(java.lang.String).
      Returns:
      the stats name
    • withStatsName

      public StarlarkScript withStatsName(String name)
      This script with its stats tagged name rather than after its file. The script itself is shared, not run again.
      Parameters:
      name - the name, made fit for a stat name as TagExtractor.sanitize(java.lang.String) does
      Returns:
      the script with the name
    • withObserver

      public StarlarkScript withObserver(ScriptCallObserver observer)
      This script with observer seeing every call into it. The script itself is shared, not run again.
      Parameters:
      observer - the observer, or null for none
      Returns:
      the script with the observer
    • withProtoSchema

      public StarlarkScript withProtoSchema(ProtoSchema schema)
      This script with a protobuf schema for its protobuf and grpc modules, so that protobuf.decode(data, type="pkg.Message") decodes with field names (and encode takes them). The script itself is shared, not run again.
      Parameters:
      schema - the schema, or null for none (the well-known types only)
      Returns:
      the script with the schema
    • protoSchema

      public ProtoSchema protoSchema()
      Returns the protobuf schema the script decodes with, or null.
      Returns:
      the protobuf schema the script decodes with, or null
    • load

      public static StarlarkScript load(Path file, StarlarkScript.Limits limits) throws IOException, ScriptException
      Loads and runs the script in file.
      Parameters:
      file - the UTF-8 script file
      limits - the bounds for top-level execution and later calls
      Returns:
      the compiled script with frozen globals
      Throws:
      IOException - if the file cannot be read
      ScriptException - if parsing, compilation or top-level execution fails
    • load

      public static StarlarkScript load(Path file, StarlarkScript.Limits limits, Map<String,?> constants) throws IOException, ScriptException
      Loads and runs the script in file, with constants as read-only globals (see ScriptedProxy.Builder.constants).
      Parameters:
      file - the UTF-8 script file
      limits - the bounds for top-level execution and later calls
      constants - the globals to copy and freeze before compilation
      Returns:
      the compiled script with frozen globals
      Throws:
      IOException - if the file cannot be read
      ScriptException - if parsing, compilation or top-level execution fails
      IllegalArgumentException - if a constant name or value is invalid
    • load

      public static StarlarkScript load(Path file, StarlarkScript.Limits limits, Map<String,?> constants, StatsRegistry stats) throws IOException, ScriptException
      Loads and runs the script in file, with constants as read-only globals and its stats module counting into stats.
      Parameters:
      file - the UTF-8 script file
      limits - the bounds for top-level execution and later calls
      constants - the globals to copy and freeze before compilation
      stats - the registry of the script's stats, or null for metrics that count nothing
      Returns:
      the compiled script with frozen globals
      Throws:
      IOException - if the file cannot be read
      ScriptException - if parsing, compilation or top-level execution fails
      IllegalArgumentException - if a constant name or value is invalid
    • compile

      public static StarlarkScript compile(String source, String name, StarlarkScript.Limits limits) throws ScriptException
      Compiles and runs source; name appears in error messages.
      Parameters:
      source - the Starlark source to compile
      name - the script name used in diagnostics
      limits - the bounds for top-level execution and later calls
      Returns:
      the compiled script with frozen globals
      Throws:
      ScriptException - if parsing, compilation or top-level execution fails
    • compile

      public static StarlarkScript compile(String source, String name, StarlarkScript.Limits limits, Map<String,?> constants) throws ScriptException
      Compiles and runs source with constants as read-only globals (see ScriptedProxy.Builder.constants); name appears in error messages.
      Parameters:
      source - the Starlark source to compile
      name - the script name used in diagnostics
      limits - the bounds for top-level execution and later calls
      constants - the globals to copy and freeze before compilation
      Returns:
      the compiled script with frozen globals
      Throws:
      ScriptException - if parsing, compilation or top-level execution fails
      IllegalArgumentException - for constants that are not valid (see ScriptedProxy.Builder.constants)
    • compile

      public static StarlarkScript compile(String source, String name, StarlarkScript.Limits limits, Map<String,?> constants, StatsRegistry stats) throws ScriptException
      Compiles and runs source with constants as read-only globals, its stats module counting into stats (ScriptStats); name appears in error messages.
      Parameters:
      source - the Starlark source to compile
      name - the script name used in diagnostics
      limits - the bounds for top-level execution and later calls
      constants - the globals to copy and freeze before compilation
      stats - the registry of the script's stats, or null for metrics that count nothing
      Returns:
      the compiled script with frozen globals
      Throws:
      ScriptException - if parsing, compilation or top-level execution fails
      IllegalArgumentException - for constants that are not valid (see ScriptedProxy.Builder.constants)
    • name

      public String name()
      The name given at compile time (the file path for loaded scripts).
      Returns:
      the diagnostic name of this script
    • defines

      public boolean defines(String function)
      Whether the script defines a function function.
      Parameters:
      function - the global name to inspect
      Returns:
      whether that global is callable
    • global

      public Object global(String name)
      The value of the global name (frozen), or null when the script sets none.
      Parameters:
      name - the global name to look up
      Returns:
      the frozen global value, or null if absent
    • call

      public Object call(String function, org.microproxy.thirdparty.starlark.eval.Mutability mu, Object... args) throws org.microproxy.thirdparty.starlark.eval.EvalException, InterruptedException
      Calls function with args, for no exchange (see call(FlowContext, String, Mutability, Object...)).
      Parameters:
      function - the global function name
      mu - the owner of values created by this call
      args - the positional Starlark arguments
      Returns:
      the function's Starlark result
      Throws:
      org.microproxy.thirdparty.starlark.eval.EvalException - if the function is absent, evaluation fails or an execution limit is reached
      InterruptedException - if the calling thread is interrupted
    • call

      public Object call(FlowContext flow, String function, org.microproxy.thirdparty.starlark.eval.Mutability mu, Object... args) throws org.microproxy.thirdparty.starlark.eval.EvalException, InterruptedException
      Calls function with args for the exchange flow. Values the call creates belong to mu, so several calls for one request can share state through it. The call is measured (steps, bytes of values created, time): with metrics, in hooks.starlark.<script>.<function>.*; in flow's totals; and by the observer. Without any of them, and without a timeout, no clock is read.
      Parameters:
      flow - the exchange the call is for, or null
      function - the global function name
      mu - the owner of values created by this call
      args - the positional Starlark arguments
      Returns:
      the function's Starlark result
      Throws:
      org.microproxy.thirdparty.starlark.eval.EvalException - if the function is absent, evaluation fails or an execution limit is reached
      InterruptedException - if the calling thread is interrupted
    • toString

      public String toString()
      Overrides:
      toString in class Object