Documentation ¶
Index ¶
- Constants
- Variables
- func AcceptsMimeType(r *http.Request, mimeType string) bool
- func NewAttemptID() uint64
- func NewSyncID() uint64
- func RunServer(tlsConfig *TLSConfig, handler http.Handler, addr string, insecure bool)
- func Sha1sum(filename string) ([]byte, error)
- type Arg
- type BaseInput
- func (input *BaseInput) Acquire()
- func (input *BaseInput) Commit(size int64)
- func (input *BaseInput) Committed() bool
- func (input *BaseInput) Delete() error
- func (input *BaseInput) Hash() string
- func (input *BaseInput) Path() string
- func (input *BaseInput) Persist() error
- func (input *BaseInput) Release(outerInput Input)
- func (input *BaseInput) Reserve(size int64)
- func (input *BaseInput) Settings() *ProblemSettings
- func (input *BaseInput) Size() int64
- func (input *BaseInput) Transmit(w http.ResponseWriter) error
- func (input *BaseInput) Verify() error
- type BroadcasterConfig
- type ByCaseName
- type ByGroupName
- type CachedInputFactory
- type CaseSettings
- type CompleteEvent
- type Config
- type Context
- type DbConfig
- type Event
- type EventCollector
- type EventFactory
- func (factory *EventFactory) NewCompleteEvent(name string, args ...Arg) *CompleteEvent
- func (factory *EventFactory) NewEvent(name string, eventType string, args ...Arg) *NormalEvent
- func (factory *EventFactory) NewIssuerClockSyncEvent() *IssuerClockSyncEvent
- func (factory *EventFactory) NewReceiverClockSyncEvent(syncID uint64) *NormalEvent
- func (factory *EventFactory) Register(collector EventCollector) error
- type FairMutex
- type GraderConfig
- type GroupSettings
- type HashReader
- type IdentityInputFactory
- type Input
- type InputFactory
- type InputManager
- func (mgr *InputManager) Add(hash string, factory InputFactory) (Input, error)
- func (mgr *InputManager) Get(hash string) (Input, error)
- func (mgr *InputManager) Insert(input Input)
- func (mgr *InputManager) MarshalJSON() ([]byte, error)
- func (mgr *InputManager) PreloadInputs(rootdir string, factory CachedInputFactory, ioLock sync.Locker) error
- func (mgr *InputManager) Reserve(size int64)
- func (mgr *InputManager) Size() int64
- type InputManagerConfig
- type InteractiveInterface
- type InteractiveSettings
- type IssuerClockSyncEvent
- type LimitsSettings
- type LiteralCaseSettings
- type LiteralCustomValidatorSettings
- type LiteralInput
- type LiteralInputFactory
- type LiteralInteractiveSettings
- type LiteralRun
- type LiteralValidatorSettings
- type Lockable
- type LoggingConfig
- type MemoryEventCollector
- type MetricsConfig
- type MultiEventCollector
- type NormalEvent
- type NullEventCollector
- type ProblemSettings
- type RefCounted
- type Run
- type RunnerConfig
- type TLSConfig
- type TracingConfig
- type V1Config
- type ValidatorSettings
- type WriterEventCollector
Constants ¶
const ( EventBegin = "B" EventClockSync = "c" EventEnd = "E" EventComplete = "X" EventInstant = "i" EventMetadata = "M" )
Variables ¶
var ( DefaultLiteralLimitSettings = LimitsSettings{ TimeLimit: 1000, MemoryLimit: 67108864, OverallWallTimeLimit: 5000, ExtraWallTime: 0, OutputLimit: 10240, ValidatorTimeLimit: 1000, } DefaultLiteralValidatorSettings = LiteralValidatorSettings{ Name: "token-caseless", } DefaultValidatorTolerance = 1e-6 )
Default values for some of the settings.
Functions ¶
func NewAttemptID ¶
func NewAttemptID() uint64
NewAttemptID allocates a locally-unique AttemptID. A counter is initialized to a random 63-bit integer on startup and then atomically incremented eacn time a new ID is needed.
func NewSyncID ¶
func NewSyncID() uint64
NewSyncID allocates a locally-unique SyncID. A counter is initialized to a random 63-bit integer on startup and then atomically incremented each time a new ID is needed.
Types ¶
type BaseInput ¶
BaseInput is an abstract struct that provides most of the functions required to implement Input.
func NewBaseInput ¶
func NewBaseInput(hash string, mgr *InputManager) *BaseInput
func (*BaseInput) Settings ¶
func (input *BaseInput) Settings() *ProblemSettings
type BroadcasterConfig ¶
type BroadcasterConfig struct { ChannelLength int EventsPort uint16 FrontendURL string PingPeriod int64 Port uint16 Proxied bool ScoreboardUpdateSecret string ScoreboardUpdateTimeout int64 // seconds TLS TLSConfig // only used if Proxied == false WriteDeadline time.Duration }
Configuration
type ByCaseName ¶
type ByCaseName []CaseSettings
func (ByCaseName) Len ¶
func (c ByCaseName) Len() int
func (ByCaseName) Less ¶
func (c ByCaseName) Less(i, j int) bool
func (ByCaseName) Swap ¶
func (c ByCaseName) Swap(i, j int)
type ByGroupName ¶
type ByGroupName []GroupSettings
func (ByGroupName) Len ¶
func (g ByGroupName) Len() int
func (ByGroupName) Less ¶
func (g ByGroupName) Less(i, j int) bool
func (ByGroupName) Swap ¶
func (g ByGroupName) Swap(i, j int)
type CachedInputFactory ¶
type CachedInputFactory interface { InputFactory // GetInputHash returns both the hash of the input for the specified // os.FileInfo. It returns ok = false in case the os.FileInfo does not refer // to an Input. GetInputHash(dirname string, info os.FileInfo) (hash string, ok bool) }
CachedInputFactory is an InputFactory that also can validate Inputs that are already in the filesystem.
type CaseSettings ¶
CaseSettings contains the information of a single test case.
type CompleteEvent ¶
type CompleteEvent struct { NormalEvent Duration int64 `json:"dur"` }
func (*CompleteEvent) Finalize ¶
func (e *CompleteEvent) Finalize()
type Config ¶
type Config struct { Broadcaster BroadcasterConfig InputManager InputManagerConfig Grader GraderConfig Db DbConfig Logging LoggingConfig Metrics MetricsConfig Tracing TracingConfig Runner RunnerConfig TLS TLSConfig }
func DefaultConfig ¶
func DefaultConfig() Config
type Context ¶
type Context struct { Config Config Log log15.Logger EventCollector EventCollector EventFactory *EventFactory // contains filtered or unexported fields }
Context
func NewContext ¶
NewContext creates a new Context from the specified Config. This also creates a Logger.
func NewContextFromReader ¶
NewContextFromReader creates a new Context from the specified reader. This also creates a Logger.
func (*Context) AppendLogSection ¶
func (*Context) Close ¶
func (context *Context) Close()
Close releases all resources owned by the context.
func (*Context) DebugContext ¶
DebugContext returns a new Context with an additional handler with a more verbose filter (using the Debug level) and a Buffer in which all logging statements will be (also) written to.
func (*Context) TraceBuffer ¶
type EventCollector ¶
type EventFactory ¶
type EventFactory struct {
// contains filtered or unexported fields
}
func NewEventFactory ¶
func NewEventFactory(processName, threadName string) *EventFactory
func (*EventFactory) NewCompleteEvent ¶
func (factory *EventFactory) NewCompleteEvent( name string, args ...Arg, ) *CompleteEvent
func (*EventFactory) NewEvent ¶
func (factory *EventFactory) NewEvent( name string, eventType string, args ...Arg, ) *NormalEvent
func (*EventFactory) NewIssuerClockSyncEvent ¶
func (factory *EventFactory) NewIssuerClockSyncEvent() *IssuerClockSyncEvent
func (*EventFactory) NewReceiverClockSyncEvent ¶
func (factory *EventFactory) NewReceiverClockSyncEvent(syncID uint64) *NormalEvent
func (*EventFactory) Register ¶
func (factory *EventFactory) Register(collector EventCollector) error
type FairMutex ¶
type FairMutex struct {
// contains filtered or unexported fields
}
fairMutex is similar to a sync.Mutex but has an outer mutex protecting the real (inner) one. This attempts to reduce the unfairness by allowing other threads to "barge in" and block the next acquisition of the mutex until they have had their chance. See https://github.com/golang/go/issues/13086 for details.
type GraderConfig ¶
type GroupSettings ¶
type GroupSettings struct { Cases []CaseSettings Name string Weight float64 }
GroupSettings contains the information of the test case groups.
type HashReader ¶
type HashReader struct {
// contains filtered or unexported fields
}
HashReader is a Reader that provides a Sum function. After having completely read the Reader, the Sum function will provide the hash of the complete stream.
func NewHashReader ¶
func NewHashReader(r io.Reader, h hash.Hash) *HashReader
NewHashReader returns a new HashReader for a given Reader and Hash.
func (*HashReader) Length ¶
func (r *HashReader) Length() int64
Length returns the number of bytes involved in the hash computation so far.
func (*HashReader) Read ¶
func (r *HashReader) Read(b []byte) (int, error)
Read calls the underlying Reader's Read function and updates the Hash with the read bytes.
func (*HashReader) Sum ¶
func (r *HashReader) Sum(b []byte) []byte
Sum returns the hash of the Reader. Typically invoked after Read reaches EOF. Will consume any non-consumed data.
type IdentityInputFactory ¶
type IdentityInputFactory struct {
// contains filtered or unexported fields
}
IdentityInputFactory is an InputFactory that only constructs one Input.
func NewIdentityInputFactory ¶
func NewIdentityInputFactory(input Input) *IdentityInputFactory
NewIdentityInputFactory returns an IdentityInputFactory associated with the provided Input.
func (*IdentityInputFactory) NewInput ¶
func (factory *IdentityInputFactory) NewInput(hash string, mgr *InputManager) Input
NewInput returns the Input provided in the constructor. Panics if the requested hash does not match the one of the Input.
type Input ¶
type Input interface { Lockable RefCounted // Path returns the path to the uncompressed representation of the Input // on-disk. Path() string // Hash is the identifier of the Input. It is typically the Git hash of the // tree that it represents. Hash() string // Commited returns true if the input has been verified and is committed into // its InputManager. Committed() bool // Size returns the number of bytes of the Input's on-disk representation. Size() int64 // Verify ensures that the version of the Input stored in the filesystem // exists and is consistent, and commits it so that it can be added to the // InputManager. It is expected that Size() returns a valid size after // Verify() returns successfully. Verify() error // Persist stores the Input into the filesystem in a form that is // easily consumed and can be verified for consistency after restarting. Persist() error // Delete removes the filesystem version of the Input to free space. Delete() error // Settings returns the problem's settings for the Input. Problems can have // different ProblemSettings on different Inputs. Settings() *ProblemSettings // Transmit sends a serialized version of the Input over HTTP. It should be a // .tar.gz file with the Content-SHA1 header set to the hexadecimal // representation of the SHA-1 hash of the file. Transmit(http.ResponseWriter) error }
Input represents a problem's input set.
Input is reference-counted, so it will keep the input in memory (and disk) while there is at least one reference to it. Once the last reference is released, it will be inserted into its associated InputManager.
type InputFactory ¶
type InputFactory interface {
NewInput(hash string, mgr *InputManager) Input
}
InputFactory creates Input objects for an InputManager based on a hash. The hash is just an opaque identifier that just so happens to be the SHA1 hash of the git tree representation of the Input.
InputFactory is provided so that the Grader and the Runner can have different implementations of how to create, read, and write an Input in disk.
type InputManager ¶
InputManager handles a pool of recently-used input sets. The pool has a fixed maximum size with a least-recently used eviction policy.
func NewInputManager ¶
func NewInputManager(ctx *Context) *InputManager
NewInputManager creates a new InputManager with the provided Context.
func (*InputManager) Add ¶
func (mgr *InputManager) Add(hash string, factory InputFactory) (Input, error)
Add associates an opaque identifier (the hash) with an Input in the InputManager.
The InputFactory is responsible to create the Input if it has not yet been created. The Input will be validated if it has not been committed to the InputManager, but will still not be accounted into the size limit since there is at least one live reference to it.
func (*InputManager) Get ¶
func (mgr *InputManager) Get(hash string) (Input, error)
Get returns the Input for a specified hash, if it is already present in the pool. If it is present, it will increment its reference-count and transfer the ownership of the reference to the caller. It is the caller's responsibility to release the ownership of the Input.
func (*InputManager) Insert ¶
func (mgr *InputManager) Insert(input Input)
Insert adds an already-created Input to the pool, possibly evicting old entries to free enough space such that the total size of Inputs in the pool is still within the limit. This should only be called when there are no references to the Input.
func (*InputManager) MarshalJSON ¶
func (mgr *InputManager) MarshalJSON() ([]byte, error)
func (*InputManager) PreloadInputs ¶
func (mgr *InputManager) PreloadInputs( rootdir string, factory CachedInputFactory, ioLock sync.Locker, ) error
PreloadInputs reads all files in path, runs them through the specified filter, and tries to add them into the InputManager. PreloadInputs acquires the ioLock just before doing I/O in order to guarantee that the system will not be doing expensive I/O operations in the middle of a performance-sensitive operation (like running contestants' code).
func (*InputManager) Reserve ¶
func (mgr *InputManager) Reserve(size int64)
Reserve evicts Inputs from the pool to make the specified size available.
func (*InputManager) Size ¶
func (mgr *InputManager) Size() int64
Size returns the total size (in bytes) of cached Inputs in the InputManager. This does not count any Inputs with live references.
type InputManagerConfig ¶
type InputManagerConfig struct {
CacheSize int64
}
type InteractiveInterface ¶
type InteractiveSettings ¶
type InteractiveSettings struct { Interfaces map[string]map[string]*InteractiveInterface Main string ModuleName string ParentLang string LibinteractiveVersion string }
InteractiveSettings contains the information needed by libinteractive to generate interactive shims.
type IssuerClockSyncEvent ¶
type IssuerClockSyncEvent struct { NormalEvent SyncID uint64 `json:"-"` }
func (*IssuerClockSyncEvent) Finalize ¶
func (e *IssuerClockSyncEvent) Finalize()
type LimitsSettings ¶
type LimitsSettings struct { ExtraWallTime int64 MemoryLimit int64 OutputLimit int64 OverallWallTimeLimit int64 TimeLimit int64 ValidatorTimeLimit int64 }
LimitsSettings represents runtime limits for the Input.
type LiteralCaseSettings ¶
type LiteralCaseSettings struct { Input string `json:"in"` ExpectedOutput string `json:"out"` Weight *float64 `json:"weight,omitempty"` }
LiteralCaseSettings stores the input, expected output, and the weight of a particular test case.
type LiteralCustomValidatorSettings ¶
type LiteralCustomValidatorSettings struct { Source string `json:"source"` Language string `json:"language"` }
LiteralCustomValidatorSettings stores the source of the program that will validate the contestant's outputs.
type LiteralInput ¶
type LiteralInput struct { Cases map[string]LiteralCaseSettings `json:"cases"` Limits *LimitsSettings `json:"limits,omitempty"` Validator *LiteralValidatorSettings `json:"validator,omitempty"` Interactive *LiteralInteractiveSettings `json:"interactive,omitempty"` }
LiteralInput is a standalone representation of an Input (although it cannot be used directly as an Input). It is useful for testing and to evaluate a run that doesn't have a problem associated with it.
type LiteralInputFactory ¶
type LiteralInputFactory struct {
// contains filtered or unexported fields
}
LiteralInputFactory is an InputFactory that will return an Input version of the specified LiteralInput when asked for an input.
func NewLiteralInputFactory ¶
func NewLiteralInputFactory( input *LiteralInput, runtimePath string, ) (*LiteralInputFactory, error)
NewLiteralInputFactory validates the LiteralInput and stores it so it can be returned when NewInput is called.
func (*LiteralInputFactory) Hash ¶
func (factory *LiteralInputFactory) Hash() string
func (*LiteralInputFactory) NewInput ¶
func (factory *LiteralInputFactory) NewInput(hash string, mgr *InputManager) Input
NewInput returns the LiteralInput that was specified as the LiteralInputFactory's Input in its constructor.
type LiteralInteractiveSettings ¶
type LiteralInteractiveSettings struct { IDLSource string `json:"idl"` ModuleName string `json:"module_name"` ParentLang string `json:"language"` MainSource string `json:"main_source"` }
LiteralInteractiveSettings stores the settings for a problem that uses libinteractive.
type LiteralRun ¶
type LiteralRun struct { Source string `json:"source"` Language string `json:"language"` Input string `json:"input"` }
LiteralRun is a standalone representation of a Run. It is useful for testing and to evaluate a run that doesn't have a problem associated with it.
type LiteralValidatorSettings ¶
type LiteralValidatorSettings struct { Name string `json:"name"` Tolerance *float64 `json:"tolerance,omitempty"` CustomValidator *LiteralCustomValidatorSettings `json:"custom_validator,omitempty"` }
LiteralValidatorSettings stores the settings for the validator, that will calculate a per-case grade. Valid values for Name are "custom", "literal", "token", "token-caseless", "token-numeric". If "custom" is chosen, a valid CustomValidator must be provided. If "token-numeric" is chosen, Tolerance must contain a numeric tolerance (typically a small number).
type Lockable ¶
type Lockable interface { Lock() Unlock() }
Lockable is the interface that sync.Mutex implements.
type LoggingConfig ¶
type MemoryEventCollector ¶
type MemoryEventCollector struct { Events []Event // contains filtered or unexported fields }
func NewMemoryEventCollector ¶
func NewMemoryEventCollector() *MemoryEventCollector
func (*MemoryEventCollector) Add ¶
func (collector *MemoryEventCollector) Add(e Event) error
func (*MemoryEventCollector) MarshalJSON ¶
func (collector *MemoryEventCollector) MarshalJSON() ([]byte, error)
func (*MemoryEventCollector) UnmarshalJSON ¶
func (collector *MemoryEventCollector) UnmarshalJSON(buf []byte) error
type MetricsConfig ¶
type MetricsConfig struct {
Port uint16
}
type MultiEventCollector ¶
type MultiEventCollector struct {
// contains filtered or unexported fields
}
func NewMultiEventCollector ¶
func NewMultiEventCollector(collectors ...EventCollector) *MultiEventCollector
func (*MultiEventCollector) Add ¶
func (collector *MultiEventCollector) Add(e Event) error
type NormalEvent ¶
type NormalEvent struct { Name string `json:"name"` Type string `json:"ph"` Timestamp int64 `json:"ts"` PID int `json:"pid"` TID int `json:"tid"` Args map[string]interface{} `json:"args,omitempty"` // contains filtered or unexported fields }
func (*NormalEvent) Finalize ¶
func (e *NormalEvent) Finalize()
type NullEventCollector ¶
type NullEventCollector struct { }
func (*NullEventCollector) Add ¶
func (collector *NullEventCollector) Add(e Event) error
type ProblemSettings ¶
type ProblemSettings struct { Cases []GroupSettings `json:"Cases"` Interactive *InteractiveSettings `json:"Interactive,omitempty"` Limits LimitsSettings `json:"Limits"` Slow bool `json:"Slow"` Validator ValidatorSettings `json:"Validator"` }
ProblemSettings represents the settings of a problem for a particular Input set.
type RefCounted ¶
type RefCounted interface { Acquire() // Unfortunately, Go always invokes the methods of an embedded type with the // embedded type as the receiver (rather than the outer type), effectively // upcasting the pointer and losing the actual type. In order to avoid that, // we need to pass the Input again as a parameter. Release(Input) }
RefCounted is the interface that provides reference-counted semantics.
Once the final reference has been released, the object is expected to release all resources.
type Run ¶
type Run struct { AttemptID uint64 `json:"attempt_id"` Source string `json:"source"` Language string `json:"language"` InputHash string `json:"input_hash"` MaxScore float64 `json:"max_score"` Debug bool `json:"debug"` }
An omegaUp run.
func (*Run) UpdateAttemptID ¶
UpdateID assigns a new AttemptID to a run.
type RunnerConfig ¶
type TracingConfig ¶
type ValidatorSettings ¶
type ValidatorSettings struct { Lang *string `json:"Lang,omitempty"` Name string `json:"Name"` Tolerance *float64 `json:"Tolerance,omitempty"` }
ValidatorSettings represents the options used to validate outputs.
type WriterEventCollector ¶
type WriterEventCollector struct {
// contains filtered or unexported fields
}
func NewWriterEventCollector ¶
func NewWriterEventCollector( output io.Writer, appending bool, ) (*WriterEventCollector, error)
func (*WriterEventCollector) Add ¶
func (collector *WriterEventCollector) Add(e Event) error