tenant

package
v0.0.0-...-86e9f11 Latest Latest
Warning

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

Go to latest
Published: Jan 7, 2024 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Overview

Package tenant encapsulates the logic and protocol-level details for managing tenant sub-processes.

Background:

In the interest of reducing the blast radius of bugs in the core query execution assembly code, we're executing queries in separate subprocesses, one for each "tenant." This ought to keep an out-of-bounds read bug from turning into cross-tenant information disclosure. However, we need to endure some unfortunate incidental complexity in order to make this strategy performant. In particular, we're trying our best to avoid having either one of the Go processes (or the kenel) from having to copy data back and forth between pipes, etc., since the query processing pipeline would like to consume as much of our memory bandwidth as we can give it.

In order to avoid copies, each of the tenant processes is launched (lazily!) with a unix control socket over which we can pass it output file descriptors. So, every request to execute a query will be passed over the control socket *along with* the file descriptor to which the query output should be written.

There are two sorts of requests that can be made to a tenant:

  • "Direct Execution" requests, which are produced by Mangager.Do, provide a query plan to a specific local tenant process, along with an output file descriptor for the tenant to write to. The tenant performs the query and writes the results to the file descriptor.

  • "Proxy Execution" requests, which are produced by tenant processes themselves, provide the ability for a tenant on one machine to "fan out" a query to multiple tenant processes across different machines. These are made available through Manager.Remote (see also: tnproto.Remote).

In practice, "split" query plans (ones that are meant to run on multiple machines) will use both of the request types above. The original ("reduction") query plan will be launched via a Direct Execution request, and then its constituent ("mapping") sub-queries will be requested by the tenant process via Proxy Execution requests.

Index

Constants

View Source
const DefaultCacheDir = "/tmp/tenant-cache"
View Source
const (
	DefaultReapInterval = time.Hour
)

Variables

View Source
var ErrOverloaded = errors.New("child overloaded")

ErrOverloaded can be returned by calls to Manager.Do when too many calls to Do are currently pending for the same tenant.

Functions

func CanSandbox

func CanSandbox() bool

CanSandbox returns whether or not tenants can be sandboxed using bwrap(1).

func Check

func Check(rc io.ReadCloser, stats *plan.ExecStats) error

Check checks the return status of the tenant error pipe returned from Manager.Do. Check blocks until the other end of the pipe has been closed, and then closes this end of the pipe.

func DefaultEnv

func DefaultEnv(cache string, id tnproto.ID) []string

DefaultEnv is the default environment-generating function for the tenant process. The tenant process should not receive all of the parent's environment variables, as the parent may have credentials stored there.

The cache argument contains the return value of filepath.Join(CacheDir, id.String()) for the CacheDir configured in the manager (see Manager.CacheDir).

It sets the following:

PATH=$PATH
SHELL=$SHELL
HOME=$HOME
LANG=C.UTF-8
CACHEDIR=<cache>

Types

type Manager

type Manager struct {
	// CacheDir is the root of the directory
	// tree used for caching data.
	CacheDir string
	// Sandbox determines if Manager
	// launches the tenant process
	// with bwrap(1)
	Sandbox bool
	// contains filtered or unexported fields
}

Manager manages the state associated with multiple tenant processes. Manager can be used to talk to arbitrary tenant processes, and it takes care of lazily launching and killing tenant processes based on their utilization.

Broadly speaking, the tenant manager has two similar responsibilities:

  1. Allow *this* process to talk to a sub-process tenant directly.
  2. Allow other tenants inside other tenant managers to connect to the tenants running locally via Manager.Remote.

func NewManager

func NewManager(cmd []string, opt ...Option) *Manager

NewManager makes a new Manager from the list of command-line arguments provided and the list of additional options.

The cmd list should contain at least one element, since the first element of the list indicates the name of the program to run.

func (*Manager) Do

func (m *Manager) Do(id tnproto.ID, key tnproto.Key, t *plan.Tree, ofmt tnproto.OutputFormat, into net.Conn) (io.ReadCloser, error)

Do sends a DirectExec message to the given tenant ID managed by m. If the tenant process has not been started yet, it is launched lazily.

Do may return ErrOverloaded if many calls to Do for the same tenant ID are outstanding simultaneously. (The current implementation determines this by bailing out of acquisition of the child lock after 1 second of inactivity.)

Once Do returns, the query has begun execution. The returned io.ReadCloser will indicate when the query has completed execution and if any errors were encountered. (Use Check to block on query execution and check the final error status.)

The result of the query is executed into the socket backing the provided net.Conn. It is the caller's responsibility to close the provided connection. (Note that sending the socket over to the tenant subprocess involves creating a duplicated file handle, so closing 'into' immediately after a call to Do will not close the connection from the perspective of the tenant process.)

func (*Manager) Quit

func (m *Manager) Quit(id tnproto.ID, key tnproto.Key) bool

Quit sends a SIGQUIT to the tenant process with the provided ID. Quit returns true if the signal was sent successfully, or false if the signal could not be sent (either because no such tenant was running or because signal(2) failed).

func (*Manager) Serve

func (m *Manager) Serve() error

Serve accepts connections from m.Remote in a loop and launches a goroutine to service each request. It does not return unless m.Stop is called or it encounters a permanent error from m.Remote.Accept

func (*Manager) Stop

func (m *Manager) Stop()

Stop performs a graceful cleanup of all of the tenant manager subprocesses.

Calling Stop more than exactly once will cause a panic.

type Option

type Option func(m *Manager)

Option is an optional argument to NewManager to indicate optional Manager configuration.

func WithCgroup

func WithCgroup(fn func(id tnproto.ID) cgroup.Dir) Option

WithCgroup sets the delegated cgroup that the Manager will use to launch tenant processes. If the returned cgroup already exists, all the processes within it will be killed before spawning a new tenant process.

func WithGCInterval

func WithGCInterval(interval time.Duration) Option

WithGCInterval is an option that can be passed to NewManager to indicate the desired process GC interval.

If interval is zero, then process GC is disabled.

func WithLogger

func WithLogger(l *log.Logger) Option

WithLogger is an option that can be passed to NewManager to have it log diagnostic information and information from child subprocesses. If WithLogger is not provided, then the children share stdout and stderr with the parent process.

For child subprocesses, each line of output to stdout and stderr will be prefixed with the ID os the subprocess.

func WithRemote

func WithRemote(l net.Listener) Option

WithRemote is an option that can be passed to NewManager to indicate the listener on which to serve remote proxy exec messages.

func WithTenantEnv

func WithTenantEnv(fn func(string, tnproto.ID) []string) Option

WithTenantEnv overrides default tenant environment function (see DefaultEnv) with another function.

Directories

Path Synopsis
Package dcache provides a cache for table data by storing files in a directory.
Package dcache provides a cache for table data by storing files in a directory.
Package tnproto defines the types and functions necessary to speak the tenant control protocol.
Package tnproto defines the types and functions necessary to speak the tenant control protocol.

Jump to

Keyboard shortcuts

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