예제 #1
0
// ReadCheckpoint reads a checkpoint structure from the durable file dfile.
func ReadCheckpoint(dfile string) (*Checkpoint, error) {
	// Fetch service info from durable fs
	f, err := durablefs.OpenFile(dfile)
	if err != nil {
		return nil, err
	}
	chk_, err := f.Read()
	if err != nil {
		return nil, err
	}
	if len(chk_) == 0 {
		return nil, circuit.NewError("no values in checkpoint durable file " + dfile)
	}
	chk, ok := chk_[0].(*Checkpoint)
	if !ok {
		return nil, circuit.NewError("unexpected checkpoint value (%#v) of type (%T) in durable file %s", chk_[0], chk_[0], dfile)
	}
	return chk, nil
}
예제 #2
0
// RuntimeProfile exposes the Go runtime profiling framework of this worker
func (s *Acid) RuntimeProfile(name string, debug int) ([]byte, error) {
	prof := pprof.Lookup(name)
	if prof == nil {
		return nil, circuit.NewError("no such profile")
	}
	var w bytes.Buffer
	if err := prof.WriteTo(&w, debug); err != nil {
		return nil, err
	}
	return w.Bytes(), nil
}
예제 #3
0
func (s *Acid) CPUProfile(duration time.Duration) ([]byte, error) {
	if duration > time.Hour {
		return nil, circuit.NewError("cpu profile duration exceeds 1 hour")
	}
	var w bytes.Buffer
	if err := pprof.StartCPUProfile(&w); err != nil {
		return nil, err
	}
	log.Printf("cpu profiling for %d sec", duration/1e9)
	time.Sleep(duration)
	pprof.StopCPUProfile()
	return w.Bytes(), nil
}
예제 #4
0
func (file *File) Read() ([]interface{}, error) {
	file.Lock()
	defer file.Unlock()

	var b block
	if err := file.dec.Decode(&b); err != nil {
		return nil, err
	}
	if b.Payload == nil {
		return nil, circuit.NewError("block without payload")
	}
	val, _, err := circuit.Import(b.Payload)
	return val, err
}
예제 #5
0
/*
	/dir
	/dir/...
	/dir/file
*/
func parse(s string) (anchor string, file, recurse bool, err error) {
	s = strings.TrimSpace(s)
	if len(s) == 0 || s[0] != '/' {
		return "", false, false, circuit.NewError("invalid anchor")
	}
	if len(s) > 3 && s[len(s)-3:] == "..." {
		recurse = true
		s = s[:len(s)-3]
	}
	_, leaf := path.Split(s)
	if _, err := circuit.ParseWorkerID(leaf); err == nil {
		return s, true, false, nil
	}
	return s, false, recurse, nil
}
예제 #6
0
func (r *Runtime) Spawn(host string, anchor []string, fn circuit.Func, in ...interface{}) (retrn []interface{}, addr circuit.Addr, err error) {

	// Catch all errors
	defer func() {
		if p := recover(); p != nil {
			retrn, addr = nil, nil
			err = circuit.NewError(fmt.Sprintf("spawn panic: %#v", p))
		}
	}()

	addr, err = worker.Spawn(host, anchor...)
	if err != nil {
		return nil, nil, err
	}

	return r.remoteGo(addr, fn, in...), addr, nil
}
예제 #7
0
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package anchorfs exposes the programming interface for accessing the anchor file system
package anchorfs

import (
	"circuit/use/circuit"
	"path"
	"strings"
	"time"
)

var (
	ErrName     = circuit.NewError("anchor name")
	ErrNotFound = circuit.NewError("not found")
)

// fs represents an anchor file system
type fs interface {
	CreateFile(string, circuit.Addr) error
	OpenFile(string) (File, error)
	OpenDir(string) (Dir, error)
	Created() []string
}

// Dir is the interface for a directory of workers in the anchor file system
type Dir interface {

	// Name returns the name of the directory
예제 #8
0
	// Expire behaves like Change except, if the expiration interval is
	// reached, it returns before a change is observed in the directory
	Expire(expire time.Duration) (children map[string]Info)

	// Close closes this directory
	Close()
}

// Info holds metadata about a node (file or directory) in the file system
type Info struct {
	Name        string // Name of the file or sub-directory
	HasBody     bool   // True if the Zookeeper node has non-empty data
	HasChildren bool   // True if the Zookeeper node has children
}

// File is an interface to a file in the durable file system
type File interface {

	// Read reads the contents of this file and returns it in the form of a slice of interfaces
	Read() ([]interface{}, error)

	// Write writes a list of interfaces to this file
	Write(...interface{}) error

	// Close closes this file
	Close() error
}

var ErrParse = circuit.NewError("parse")
예제 #9
0
func fileRecover(pe *error) {
	if p := recover(); p != nil {
		*pe = circuit.NewError("server died")
	}
}
예제 #10
0
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package zdurablefs implements a durable file system using Apache Zookeeper
package zdurablefs

import (
	"circuit/use/circuit"
	zookeeper "github.com/petar/gozk"
	"path"
)

var (
	ErrClosed = circuit.NewError("durable file system: closed")
)

// FS implements a durable file system on top of Zookeeper
type FS struct {
	conn  *zookeeper.Conn
	zroot string
}

func New(conn *zookeeper.Conn, zroot string) *FS {
	return &FS{conn: conn, zroot: zroot}
}

func (fs *FS) Remove(fpath string) error {
	return fs.conn.Delete(path.Join(fs.zroot, fpath), -1)
}
예제 #11
0
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package API implements aa REST HTTP API proxy for a sumr database
package api

import (
	"circuit/app/sumr/client"
	"circuit/kit/sched/limiter"
	"circuit/use/circuit"
)

var (
	ErrMode      = circuit.NewError("write operation on read-only API")
	ErrBackend   = circuit.NewError("backend")
	ErrFormat    = circuit.NewError("format")
	ErrFields    = circuit.NewError("bad fields")
	ErrNoValue   = circuit.NewError("missing value")
	ErrNoFeature = circuit.NewError("missing feature")
	ErrFieldType = circuit.NewError("field type not string")
	ErrTime      = circuit.NewError("time format")
)

// API implements a RESTful HTTP API server that accepts JSON requests and
// translates them to in-circuit requests to the sumr database cluster.
// It can be viewed as a proxy between an external HTTP-capable technology, and
// the circuit-backed sumr datastore.
// As an added convenience the HTTP API canonically and transparently hashes
// JSON values to sumr 64-bit keys. This allows upstream users, e.g. a PHP web app,
예제 #12
0
func read(rec []string, v interface{}) error {
	w := reflect.ValueOf(v)
	for w.Kind() == reflect.Ptr || w.Kind() == reflect.Interface {
		w = w.Elem()
	}
	//t := w.Type()
	for i := 0; i < w.NumField(); i++ {
		f := w.Field(i)
		switch f.Kind() {
		case reflect.Bool:
			u, err := strconv.ParseBool(rec[i])
			if err != nil {
				return err
			}
			f.SetBool(u)

		case reflect.Int8:
			u, err := strconv.ParseInt(rec[i], 10, 8)
			if err != nil {
				return err
			}
			f.SetInt(u)
		case reflect.Int16:
			u, err := strconv.ParseInt(rec[i], 10, 16)
			if err != nil {
				return err
			}
			f.SetInt(u)
		case reflect.Int32, reflect.Int:
			u, err := strconv.ParseInt(rec[i], 10, 32)
			if err != nil {
				return err
			}
			f.SetInt(u)
		case reflect.Int64:
			u, err := strconv.ParseInt(rec[i], 10, 64)
			if err != nil {
				return err
			}
			f.SetInt(u)

		case reflect.Uint8:
			u, err := strconv.ParseUint(rec[i], 10, 8)
			if err != nil {
				return err
			}
			f.SetUint(u)
		case reflect.Uint16:
			u, err := strconv.ParseUint(rec[i], 10, 16)
			if err != nil {
				return err
			}
			f.SetUint(u)
		case reflect.Uint32, reflect.Uint:
			u, err := strconv.ParseUint(rec[i], 10, 32)
			if err != nil {
				return err
			}
			f.SetUint(u)
		case reflect.Uint64:
			u, err := strconv.ParseUint(rec[i], 10, 64)
			if err != nil {
				return err
			}
			f.SetUint(u)

		case reflect.Uintptr:
			return circuit.NewError("unsupported field kind uintptr")

		case reflect.Float32:
			u, err := strconv.ParseFloat(rec[i], 32)
			if err != nil {
				return err
			}
			f.SetFloat(u)
		case reflect.Float64:
			u, err := strconv.ParseFloat(rec[i], 64)
			if err != nil {
				return err
			}
			f.SetFloat(u)

		case reflect.Complex64:
			return circuit.NewError("unsupported field kind complex64")

		case reflect.Complex128:
			return circuit.NewError("unsupported field kind complex128")

		case reflect.Array:
			return circuit.NewError("unsupported field kind array")

		case reflect.Chan:
			return circuit.NewError("unsupported field kind chan")

		case reflect.Func:
			return circuit.NewError("unsupported field kind func")

		case reflect.Interface:
			return circuit.NewError("unsupported field kind interface")

		case reflect.Map:
			return circuit.NewError("unsupported field kind map")

		case reflect.Ptr:
			return circuit.NewError("unsupported field kind ptr")

		case reflect.Slice:
			return circuit.NewError("unsupported field kind slice")

		case reflect.String:
			f.SetString(rec[i])

		case reflect.Struct:
			return circuit.NewError("unsupported field kind struct")

		case reflect.UnsafePointer:
			return circuit.NewError("unsupported field kind UnsafePointer")

		default:
			return circuit.NewError("unknown field kind")
		}
	}
	return nil
}
예제 #13
0
// Copyright 2013 Tumblr, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package transport

import "circuit/use/circuit"

var (
	ErrEnd           = circuit.NewError("end")
	ErrAlreadyClosed = circuit.NewError("already closed")
	errCollision     = circuit.NewError("conn id collision")
	ErrNotSupported  = circuit.NewError("not supported")
	ErrAuth          = circuit.NewError("authentication")
)