proxy

package module
v0.0.26 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 12, 2022 License: CC0-1.0 Imports: 10 Imported by: 0

Documentation

Overview

Package proxy provides a proxy that allows computer algebra systems, such as Magma, to communicate with the pcas infrastructure. Communication with the computer algebra system, which we will call CAS in what follows, takes place over a socket, in JSON format.

CASs should begin by connecting to the port and writing a JSON object containing configuration options, of the form

{
	"SendLengthPrefix":	bool
}

where bool is either true or false. If bool is true then the proxy writes JSON objects to the port as strings of the form

s\nt

where s is a string representation of an integer N, t is a string containing the JSON, and t has size N bytes. If bool is false then the proxy writes JSON objects to the port as strings of the form

t

as above, without the length prefix.

CAS may then send further JSON objects to the proxy, one at a time, as follows. Each object should take the form

{
	"Endpoint":	s,
	...
}

where s is a string that specifies the endpoint (see below) and "..." represents additional fields as described below. After an object is received, proxy will write a response to the port, which is a JSON object of the form

{
	"Error":	errMsg,	[string, possibly ""]
	"Result":	r	[JSON object, possibly {}]
}

It is possible for Result to be non-trivial even if errMsg is not "".

Logger

Objects should take the form

{
	"Endpoint":	"logger",
	"Log":		l,		[string, the name of a log]
	"Message":	m		[string, a log message]
}

This attempts to log the message m to the log l on the pcas log server. The CAS should then read the response, which is a JSON object as above with r empty. The address and port of the logging server are set via command-line options to the proxy.

Keyvalue endpoints: kvdb, mongodb, and postgres

There are three endpoints that provide key-value database: kvdb, mongodb, and postgres. In what follows, a keyvalue record is represented by a JSON object with keys that are strings and values that are either strings, integers which will fit in an int64, or booleans. A keyvalue database is represented by a JSON object in one of the following formats:

{
	"Backend":	"kvdb",
	"AppName":	appName,	[optional, string, the application to identify ourselves as to the database]
	"Host":		hostName,	[optional, string, the name of the database server]
	"Port":		portNumber,	[optional, integer, the port number on the database server]
	"Type":		dbType,		[optional, string, the type of the database]
	"Name":		dbName		[string, the name of the database]
}

{
	"Backend":	"mongodb",
	"AppName":	appName,	[optional, string, the application to identify ourselves as to the database]
	"Hosts":	hostNames,	[optional, sequence of strings, the hostnames of the database servers]
	"Username":	username,	[optional, string, the username to connect as]
	"Password":	password,	[optional, string, the password to connect with]
	"PasswordSet":	passwordSet,	[optional, boolean, whether or not a password has been set]
	"ReadConcern":	readConcern,	[optional, string, the MongoDB read concern to use ("available", "linearizable", "local", or "majority")]
	"WriteConcern":	writeConcern,	[optional, string, the MongoDB write concern to use ("majority" or "writeN")]
	"WriteN":	writeN,		[optional, integer, the number of writes to confirm. Only relevant if the write concern is "writeN"]
	"WriteJournal":	writeJournal,	[optional, boolean, whether to require confirmation of journal writes]
	"Name":			dbName                [string, the name of the database]
}

{
	"Backend":		"postgres",
	"AppName":		appName,	[optional, string, the application to identify ourselves as to the database]
	"Hosts":		hostNames,	[optional, sequence of strings, the hostnames of the database servers]
	"Username":		username,	[optional, string, the username to connect as]
	"Password":		password,	[optional, string, the password to connect with]
	"PasswordSet":		passwordSet,	[optional, boolean, whether or not a password has been set]
	"ConnectTimeout":	timeout,	[optional, integer, the maximum wait for a connection in seconds]
	"RequireSSL":		requireSSL,	[optional, boolean, whether or not to require SSL]
	"FastCopy":		fastCopy,	[optional, boolean, whether or not to enable fast Copy]
	"Name":			dbName		[string, the name of the database]
}

A sort order is represented by a JSON array of length one or more

[ {"key_1": n_1}, {"key_2": n_2}, ..., {"key_r": n_r} ]

where n_i is either +1 (for ascending) or -1 (for descending), and the sort order is lexicographical with respect to key_1, key_2, ... , key_r.

CAS can send one of various possible keyvalue requests, as follows.

kvdb/mongodb/postgres: list_tables

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"list_tables",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
}

This requests a list of the tables in the specified database. The CAS should then read the response, which is a JSON object as above with r equal to {"Tables": [s_1,s_2,...,s_k]} where the strings t_i are the names of the tables.

kvdb/mongodb/postgres: create_table

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"create_table",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Template":	rec		[JSON object, a keyvalue record as above]
}

This creates the table named tableName. The CAS should then read the response, which is a JSON object as above with r empty.

kvdb/mongodb/postgres: delete_table

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"delete_table",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
}

This deletes the table named tableName. The CAS should then read the response, which is a JSON object as above with r empty.

kvdb/mongodb/postgres: rename_table

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"rename_table",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"OldName":	oldTableName,	[string, the old table name]
	"NewName":	newTableName,	[string, the new table name]
}

This renames a table in the specified database from oldTableName to newTableName. The CAS should then read the response, which is a JSON object as above with r empty.

kvdb/mongodb/postgres: describe_table

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"describe_table",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
}

This returns a best-guess template for the data in the table named tableName. The CAS should then read the response, which is a JSON object as above with keys as strings and values that are strings in the set { "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "bool", "string", "slice", "float64" }. The values describe the datatype of the corresponding keys. The value "slice" indicates a slice of bytes.

kvdb/mongodb/postgres: defaults

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"defaults",
}

This returns the default settings for the given endpoint. The CAS should read the response, which is a JSON object representing a keyvalue database, as above.

kvdb/mongodb/postgres: insert

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"insert",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Record":	rec		[JSON object, a keyvalue record as above]
}

This inserts the specified record into the specified table in the specified database. The CAS should then read the response, which is a JSON object as above with r equal to {"Result": n} where n is the number of records inserted (0 or 1).

kvdb/mongodb/postgres: update

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"update",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Selector":	selector,	[JSON object, a keyvalue record as above]
	"Where":	sqlString,	[string, containing SQL]
	"Replacement":	replacement	[JSON object, a keyvalue record as above]
}

This updates all records in the specified table in the specified database that match selector or sqlString, setting the keys present in replacement to their corresponding values. The CAS should then read the response, which is a JSON object as above with r equal to {"Result": n} where n is the number of records updated. Precisely one of "Selector" and "Where" should be present.

kvdb/mongodb/postgres: delete

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"delete",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Selector":	selector,	[JSON object, a keyvalue record as above]
	"Where":	sqlString	[string containing SQL]
}

This deletes all records in the specified table in the specified database that match selector or sqlString. The CAS should then read the response, which is a JSON object as above with r equal to {"Result": n} where n is the number of records deleted. Precisely one of "Selector" and "Where" should be present.

kvdb/mongodb/postgres: count

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"count",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Selector":	selector,	[JSON object, a keyvalue record as above]
	"Where":	sqlString	[string containing SQL]
}

This counts the records in the specified table in the specified database that match selector or sqlString. The CAS should then read the response, which is a JSON object as above with r equal to {"Result": n} where n is the number of such records. Precisely one of "Selector" and "Where" should be present.

kvdb/mongodb/postgres: select

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"select",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Selector":	selector,	[JSON object, a keyvalue record as above]
	"Where":	sqlString,	[string containing SQL]
	"Template":	template,	[JSON object, a keyvalue record as above]
	"Sort":	order,			[JSON array, a sort order as above]
	"Limit":	limit		[optional, integer, the maximum number of records to return]
	"BufferSize": n			[optional, non-negative integer, if positive then set the buffer size to n]
}

This selects all records in the specified table in the specified database that match selector or sqlString, with results in the form specified by template and the sort order specified by order (which is optional). The CAS should then read the response, which is a JSON object as above with r of one of the following two forms

{}

{
	"ULID":	ulid
}

Here ulid is a ULID [https://github.com/ulid/spec] identifying the results set. In the first case there was an error, which is described by the string errMsg. Precisely one of "Selector" and "Where" should be present in the request.

kvdb/mongodb/postgres: advance

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"advance",
	"ULID":		ulid,		[string, the ULID that identifies the results set]
}

This advances the iterator for the results set specified by ulid. The CAS should then read the response, which is a JSON object as above with r of one of the following three forms.

{}

{
	"ULID":	ulid	[string, the ULID that was provided in the request]
}

{
	"ULID":		ulid	[string, the ULID that was provided in the request]
	"Record":	record	[JSON object, a keyvalue record as above]
}

In the first case there was an error, which is described by the string errMsg. In the second case there was no error, so errMsg is "", but iteration is finished and so there is no record to return. In the third case there was no error, so errMsg is "", and record is the next record.

kvdb/mongodb/postgres: close

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"close",
	"ULID":		ulid,		[string, the ULID that identifies the results set]
}

Closes the iterator for the results set specified by ulid. The CAS should then read the response, which is a JSON object as above with r empty.

kvdb/mongodb/postgres: add_index

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"add_index",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Key": 		key,		[string, the key on which to add an index]
}

This adds an index on the specified key in the specified table and database. The CAS should then read the response, which is a JSON object as above with r empty.

kvdb/mongodb/postgres: add_unique_index

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"add_unique_index",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Key": 		key,		[string, the key on which to add a unique index]
}

This adds an index on the specified key in the specified table and database and the constraint that, for each value of this key, there is at most one record in the table with that value. The CAS should then read the response, which is a JSON object as above with r empty.

kvdb/mongodb/postgres: delete_index

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"delete_index",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Key": 		key,		[string, the key for which to delete the index]
}

This deletes the index on the specified key in the specified table and database, if present. The CAS should then read the response, which is a JSON object as above with r empty.

kvdb/mongodb/postgres: list_indices

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"list_indices",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
}

This requests a list of the keys in the specified table and database for which indices are present. The CAS should then read the response, which is a JSON object of the following two forms.

{}

{
	"Indices":	S	[JSON array of strings, the keys for which indices are present]
}

In the first case there was an error, which is described by the string errMsg; in the second case the request succeeded.

kvdb/mongodb/postgres: add_keys

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"add_keys",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Record":	rec		[JSON object, a keyvalue record as above]
}

This updates each record R in the specified table and database, adding any keys in rec that are not already present along with the corresponding values. Any keys that are already present in R will be left unmodified. The CAS should then read the response, which is a JSON object as above with r empty.

kvdb/mongodb/postgres: delete_keys

{
	"Endpoint":	endpoint,	[string, one of "kvdb", "mongodb", and "postgres"]
	"Operation":	"delete_keys",
	"Database":	db,		[JSON object, a keyvalue database specification as above]
	"Table":	tableName,	[string, the table name]
	"Keys":	S		[JSON array of strings, the keys to be deleted]
}

This updates each record in the specified table and database, deleting the specified keys if present. The CAS should then read the response, which is a JSON object as above with r empty.

Fs

Metadata for a file or directory on an fs server is represented by a JSON object of the form

{
	"Path":			p,	[string, the full path to the file or directory]
	"Size":			n,	[integer, the size of the file contents]
	"ModificationTime":	t,	[integer, the time expressed as number of seconds since 1 Jan 1970]
	"IsDir":		isDir,	[boolean, true if and only if p is a directory]
}

fs: defaults

{
	"Endpoint":	"fs",
	"Operation":	"defaults",
}

This requests the default configuration for fs. The CAS should then read the response, which is a JSON object as above with r of the form

{
	"Address":	address	[string, the address of the fs server]
}

fs: metadata

{
	"Endpoint":	"fs",
	"Operation":	"metadata",
	"Address": 	a,	[string, the address of the fs server]
	"Path": 	p	[string, the full path to the file or directory]
}

This requests metadata for the file or directory on a with path p. The CAS should then read the response, which is a JSON object as above with r of the form

{
	"Metadata":	m	[a JSON object representing metadata, as above]
}

If the path p does not exist then the error "path does not exist" will be returned.

fs: is_empty_directory

{
	"Endpoint":	"fs",
	"Operation":	"is_empty_directory",
	"Address":	a,	[string, the address of the fs server]
	"Path":		p	[string, the full path to the file or directory]
}

The CAS should then read the response, which is a JSON object as above with r of the form

{
	"IsEmptyDirectory":	b	[boolean, true if and only if p exists on a and is an empty directory]
}

If the path p does not exist, then the error "path does not exist" will be returned.

fs: mkdir

{
	"Endpoint":	"fs",
	"Operation":	"mkdir",
	"Address":	a,	[string, the address of the fs server]
	"Path":		p,	[string, the full path to the file or directory]
	"Recursive":	b,	[boolean, whether or not we should recursively create intermediate directories]
}

Makes an empty directory on a with the path p. The path p should not already exist. The CAS should then read the response, which is a JSON object as above with r empty.

fs: upload

{
	"Endpoint":	"fs",
	"Operation":	"upload",
	"Address":	a,	[string, the address of the fs server]
	"Src":		src	[string, the full path to the source file or directory]
	"Dst":		dst	[string, the full path to the destination file or directory]
}

Requests the file or directory src on the local file system be uploaded to the file or directory dst on a. If src is a file then dst must not already exist, and will be created. If src is a directory then dst must either not exist, in which case it will be created, or must be an empty directory; in either case the contents of src are uploaded recursively to dst.

The CAS should then read the response, which is a JSON object as above with r empty.

fs: download

{
	"Endpoint":	"fs",
	"Operation":	"download",
	"Address":	a,	[string, the address of the fs server]
	"Src":		src	[string, the full path to the source file or directory]
	"Dst":		dst	[string, the full path to the destination file or directory]
}

Requests the file or directory src on a be downloaded to the file or directory dst on the local file system. If src is a file then dst must not already exist, and will be created. If src is a directory then dst must either not exist, in which case it will be created, or must be an empty directory; in either case the contents of src are downloaded recursively to dst.

The CAS should then read the response, which is a JSON object as above with r empty.

fs: delete

{
	"Endpoint":	"fs",
	"Operation":	"delete",
	"Address":	a,	[string, the address of the fs server]
	"Recursive":	b,	[boolean, true if and only if we should delete recursively]
	"Path":		p	[string, the full path to the file or directory]
}

Requests that the file or directory with path p be deleted from a. If p is a directory and b is set to true, the contents of p are recursively deleted; otherwise, if p is a directory then it must be empty.

The CAS should then read the response, which is a JSON object as above with r empty.

fs: dir

{
	"Endpoint":	"fs",
	"Operation":	"dir",
	"Address":	a,	[string, the address of the fs server]
	"Path":		p	[string, the full path to the file or directory]
}

This requests metadata for all files and directories in the directory with path p on a. The CAS should then read the response, which is a JSON object as above with r of one of the following two forms

{}

{
	"ULID":	ulid
}

Here ulid is a ULID [https://github.com/ulid/spec] identifying the dir request. In the first case there was an error, which is described by the string errMsg.

fs: advance

{
	"Endpoint":	"fs"
	"Operation":	"advance",
	"ULID":		ulid,	[string, the ULID that identifies the dir request]
}

This advances the iterator for the dir request specified by ulid. The CAS should then read the response, which is a JSON object as above with r of one of the following three forms.

{}

{
	"ULID":	ulid	[string, the ULID that was provided in the request]
}

{
	"ULID":		ulid	[string, the ULID that was provided in the request]
	"Metadata":	m	[JSON object representing metadata, as above]
}

In the first case there was an error, which is described by the string errMsg. In the second case there was no error, so errMsg is "", but iteration is finished and so there is no metadata to return. In the third case there was no error, so errMsg is "", and m is the next item of metadata.

fs: close

{
	"Endpoint":	"fs",
	"Operation":	"close",
	"ULID":		ulid,	[string, the ULID that identifies the dir request]
}

Closes iteration for the dir request specified by ulid. The CAS should then read the response, which is a JSON object as above with r empty.

Metrics

Tags for a metrics point are represented by a JSON object of the form

{
	k_1:	v_1,
	k_2:	v_2,
	...,
	k_n:	v_n,
}

where both the keys k_1,...,k_n and the values v_1,...,v_n are strings.

metrics: defaults

{
	"Endpoint":	"metrics",
	"Operation":	"defaults",
}

The CAS should read the response, which is a JSON object as above with r of the form

{
	"Address":	address	[string, the address of the metrics server]
}

metrics: set_default_tags

{
	"Endpoint":	"metrics",
	"Operation":	"set_default_tags",
	"Tags":		T,	[JSON object representing tags, as above]
}

Sets the default tags, to be submitted with every point, to T. The CAS should then read the response, which is a JSON object as above with r empty.

metrics: submit_duration

{
	"Endpoint":	"metrics",
	"Operation":	"submit_duration",
	"Name":		s,	[the name of the point]
	"Key":		k,	[the key of the field, a string]
	"Value":	v,	[the value of the field, a floating point number of seconds]
	"Tags":		T,	[optional, JSON object representing tags as above]
}

Submits a metrics point with name s, a single field {k:v}, where v is a duration, and the default tags plus the tags in T. In case of disagreement, tags in T override the defaults. The CAS should then read the response, which is a JSON object as above with r empty.

metrics: submit_boolean

{
	"Endpoint":	"metrics",
	"Operation":	"submit_boolean",
	"Name":		s,	[the name of the point]
	"Key":		k,	[the key of the field, a string]
	"Value":	v,	[the value of the field, a boolean]
	"Tags":		T,	[optional, JSON object representing tags as above]
}

Submits a metrics point with name s, a single field {k:v}, where v is a boolean, and the default tags plus the tags in T. In case of disagreement, tags in T override the defaults. The CAS should then read the response, which is a JSON object as above with r empty.

metrics: submit_string

{
	"Endpoint":	"metrics",
	"Operation":	"submit_string",
	"Name":		s,	[the name of the point]
	"Key":		k,	[the key of the field, a string]
	"Value":	v,	[the value of the field, a string]
	"Tags":		T,	[optional, JSON object representing tags as above]
}

Submits a metrics point with name s, a single field {k:v}, where v is a string, and the default tags plus the tags in T. In case of disagreement, tags in T override the defaults. The CAS should then read the response, which is a JSON object as above with r empty.

metrics: submit_integer

{
	"Endpoint":	"metrics",
	"Operation":	"submit_integer",
	"Name":		s,	[the name of the point]
	"Key":		k,	[the key of the field, a string]
	"Value":	v,	[the value of the field, a 64-bit integer]
	"Tags":		T,	[optional, JSON object representing tags as above]
}

Submits a metrics point with name s, a single field {k:v}, where v is a 64-bit integer, and the default tags plus the tags in T. In case of disagreement, tags in T override the defaults. The CAS should then read the response, which is a JSON object as above with r empty.

Rangedb

Ranges are represented as JSON objects of the form

{
	"Range":	[I_1,I_2,...,I_n]
}

where each I_k is either of the form {"Interval": [a,b]} where a and b are 64-bit integers, in which case it represents the interval [a,b], or the form {"Element": n}, where n is a 64-bit integer, in which case it represents the interval [n,n]. The intervals may be empty or may overlap.

Entries in ranges are 64-bit integers. Times are expressed as 64-bit integer numbers of nanoseconds since 1 January 1970 UTC. Durations are expressed as strings that can be parsed by the Go function time.ParseDuration.

rangedb: defaults

{
	"Endpoint":	"rangedb",
	"Operation":	"defaults",
}

The CAS should read the response, which is a JSON object as above with r of the form

{
	"Address":	address,	[string, the address of the rangedb server]
}

rangedb: create

{
	"Endpoint":		"rangedb",
	"Operation":		"create",
	"Name":			name,		[string, the name of the range]
	"Range":		entries,	[JSON object representing a range, as above]
	"Lifetime":		lifetime,	[duration, the lifetime of entries in the range]
	"MaxRetries":		m,		[optional, integer, the maximum number of times an entry in the range may be retried]
	"MaxConcurrency":	n,		[optional, integer, the maximum number of simultaneously active entries in the range]
}

This creates a range with the given name, entries, and lifetime. The maximum number of retries is set to m and the maximum concurrency to n. The CAS should then read the response, which is a JSON object as above with r empty.

rangedb: delete

{
	"Endpoint":	"rangedb",
	"Operation":	"delete",
	"Name":		name,		[string, the name of the range]
}

Deletes the range with the given name. The CAS should then read the response, which is a JSON object as above with r empty.

rangedb: next

{
	"Endpoint":	"rangedb",
	"Operation":	"next",
	"Name":		name,		[string, the name of the range]
	"AppName":	appName, 	[optional, string, the application name to send to the rangedb server]
	"Timeout":	T,		[duration, the maximum time to wait for an entry]
}

The CAS should then read the response, which is a JSON object as above with r of one of the following two forms:

{}

{"Entry": e}

In the first case there was an error, which is described by the string errMsg. In the second case e is a JSON object of the form

{
	"ULID":		u,	[string, a ULID identifying the entry]
	"Value":	n,	[integer, the value of the entry]
	"Deadline":	T,	[time, the time at which this entry will go stale]
	"Failures":	f,	[integer, the number of times this entry has failed]
}

that represents the next entry in the range.

rangedb: success/error/requeue/fatal

{
	"Endpoint":	"rangedb",
	"Operation":	op,	[string, the operation, which is one of "success", "error", "requeue", "fatal"]
	"ULID":		u,	[string, the ULID that identifies the entry]
}

Informs the rangedb server that the entry with the given ULID has succeeded (if operation is "success"), or has entered an error state (if the operation is "error"), or should be requeued (if the operation is "requeue"), or has experienced a fatal error (if the operation is "fatal"). The CAS should then read the response, which is a JSON object as above with r empty.

rangedb: list

{
	"Endpoint":	"rangedb",
	"Operation":	"list",
}

The CAS should then read the response, which is a JSON object as above with r of the form:

{
	"Ranges": S	[JSON array of strings, the names of the known ranges]
}

rangedb: status

{
	"Endpoint":	"rangedb",
	"Operation":	"status",
	"Name":		name,		[string, the name of the range]
}

The CAS should then read the response, which is a JSON object as above with r of one of the following two forms:

{}

{"Status": S}

In the first case there was an error, which is described by the string errMsg. In the second case S is a JSON object of the form

{
	"Pending":	p,		[a JSON object representing a range, as above]
	"Active":	a,		[a JSON object representing a range, as above]
	"Succeeded":	s,		[a JSON object representing a range, as above]
	"Failed":	f,		[a JSON object representing a range, as above]
}

and p, a, s, and f contain the pending, active, succeeded, and failed entries in the range.

rangedb: info

{
	"Endpoint":	"rangedb",
	"Operation":	"info",
	"Name":		name,		[string, the name of the range]
	"Entry":	n,		[integer, the entry in the range]
}

The CAS should then read the response, which is a JSON object as above with r of one of the following two forms:

{}

{"Info": S}

In the first case there was an error, which is described by the string errMsg. In the second case S is a JSON object of the form

{
	"Value":	n,	[integer, the value of the entry]
	"State":	s,	[string, the state of the entry, which is one of "Pending", "Active", "Succeeded",	 "Failed"]
	"AppName":	a,	[string, the application name provided by the client to which the entry was assigned]
	"Start":	T1,	[time, the time the entry was assigned]
	"Deadline":	T2,	[time, the time at which this entry will go stale]
	"Failures":	f,	[integer, the number of times this entry has failed]
}

Gob

Objects should take the form

{
	"Endpoint":	"gob",
	"Operation": op,	[string, either "encode" or "decode"]
	"Universe":	u,		[string, specifying the universe of x]
	"Object":	s		[string, specifying an object x to encode or decode]
}

The string u here should be exactly "[integers]", as currently only gob encoding/decoding of integer sequences is supported.

The CAS should then read the response, which is a JSON object as above with r of the form:

{
	"Object": s	[string]
}

where s is the base-64 encoding of the gob encoding of x, if the operation is "encode", and a string representation of the object x if the operation is "decode".

Version

Objects should take the form

{
	"Endpoint":	"version",
	"Operation":	"get_version"
}

The CAS should then read the response, which is a JSON object as above with r of the form:

{
	"Version":	S1,	[string, the version of the system running the proxy]
	"Commit":	S2,	[string, the git commit for the running proxy]
	"GoArch":	S3,	[string, the value of GOARCH for the system running the proxy]
	"GoOs":		S4	[string, the value of GOOS for the system running the proxy]
}

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Log         log.Interface // the logger
	SSLCert     []byte        // the SSL certificate
	SSLDisabled bool          // Is SSL disabled?
}

Config describes the options that can be set on a proxy

func (*Config) FlagSets

func (c *Config) FlagSets() []flag.Set

FlagSets returns the slice of flagsets that contains e.FlagSet for each registered endpoint e.

func (*Config) NewSet

func (c *Config) NewSet() flag.Set

NewSet returns the flagset defined by c. This contains, for each registered endpoint e, the flag -e that activates e and the flag e.Flag.

func (*Config) Options

func (c *Config) Options() *Options

Options returns the *Options defined by c.

type Encoder

type Encoder interface {
	Encode(interface{}) error
}

Encoder is an interface satisfied by *json.Encoder

func NewLengthPrefixEncoder

func NewLengthPrefixEncoder(w io.Writer) Encoder

NewLengthPrefixEncoder returns a new Encoder that writes length-prefixed JSON to w.

type Endpoint

type Endpoint struct {
	Name    string                                    // the name of the endpoint
	Create  func(*Options) (Handler, Teardown, error) // the creation function for the endpoint
	Flag    flag.Flag                                 // an optional flag, to appear in the flagset proxy.NewSet()
	FlagSet flag.Set                                  // an optional flag.Set, to be added to the slice of flagsets proxy.FlagSets()
}

Endpoint describes an endpoint

func (*Endpoint) Register

func (E *Endpoint) Register()

Register registers the endpoint handler E. This must only be called from init functions, otherwise a race condition will result.

type Handler

type Handler func(map[string]interface{}) (map[string]interface{}, error)

Handler is a function that handles requests for a particular endpoint

type Options

type Options struct {
	Log         log.Interface // the logger
	SSLCert     []byte        // the SSL certificate
	SSLDisabled bool          // Is SSL disabled?
}

Options describes the options that a proxy can set on an endpoint

type Stopper

type Stopper interface {
	// Stop stops the server
	Stop()
}

Stopper is an interface satisfied by our server

func Start

func Start(ln net.Listener, cfg *Config) (Stopper, error)

Start starts the server with the given listener and configuration.

type Teardown

type Teardown func()

Teardown is a function that cleans up before exiting

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL