pandora

package
v0.0.0-...-cf82ea8 Latest Latest
Warning

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

Go to latest
Published: Jan 30, 2020 License: MIT, MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// MaxSize define the max size that any message can have
	MaxSize = 4096
	// Key is too short to be used by the given function
	ErrKeyTooShort = ApiError("key is too short")

	// When the given input is too short to be processed by the given function
	ErrInputTooShort = ApiError("input is to short to process")

	// Header isn't a valid utf8 string
	ErrInvalidHeaderEncoding = ApiError("header should be a valid utf-8")

	// ErrMessageToBig the message data is larger than MaxSize
	ErrMessageToBig = ApiError("message is too big. max size is " + string(MaxSize))

	// ErrNilBody the body passed is nil
	ErrNilBody = ApiError("body is nil")

	// ErrInvalidHeaderEncoding means that a mailbox (sender or receiver) is invalid
	ErrInvalidMailBox = ApiError("invalid mailbox")

	// The sender wasn't found on the server
	ErrSenderNotFound = ApiError("sender not found")

	// The receiver wasn't found on the server
	ErrReceiverNotFound = ApiError("receiver not found")

	// Unable to change the status
	ErrUnableToChangeStatus = ApiError("unable to change status")

	// No messages that match the criteria at this moment
	ErrNoMessages = ApiError("no messages at this moment")

	// Body field used to store the sender
	KeySender = "sender"

	// Body field used to store the receiver
	KeyReceiver = "receiver"

	// Body field used to store the client time
	KeyClientTime = "clientTime"

	// Key used by the client to inform for how long it
	// want to keep the message locked
	KeyLeaseTime = "leaseTime"

	DefaultLeaseTime = time.Minute * 5
)
View Source
const (
	// StatusConfirmed means that a message was received and processed
	StatusConfirmed = AckStatus(1)
	// StatusRejected means that a message was received but rejected by the client
	StatusRejected = AckStatus(2)
	// StatusTimeout means that a message was sent but the client didn't sent a valid Ack
	StatusTimeout = AckStatus(4)
	// StatusNotDelivered means that a message is waiting for delivery on the queue
	StatusNotDelivered = AckStatus(8)
)

Variables

This section is empty.

Functions

func PrintKeyString

func PrintKeyString(k Key) string

PrintKeyString uses the default KeyPrinter to print a key

Types

type AckStatus

type AckStatus byte

AckStatus define the list of possible status for a given message'

func (AckStatus) String

func (a AckStatus) String() string

type ApiError

type ApiError string

ApiError is used to define the possible error types

func (ApiError) Error

func (ae ApiError) Error() string

Error implement the error interface

type BlobStore

type BlobStore interface {
	// PutData take data and returns the key under which that data
	// can be retreived later.
	//
	// If key is large enough to hold the Key, then no allocation is done.
	//
	// Is valid to pass nil as "key"
	PutData(key Key, data []byte) (Key, error)

	// GetData will return the contents under key to the user,
	// if the key isn't found, then nil, nil is returned.
	//
	// If out is large enough to hold the data, no allocation is done,
	// otherwise a new buffer is used.
	//
	// Is valid to pass nil as out
	GetData(out []byte, key Key) ([]byte, error)

	// UpdateRef will change the ref-count of the given key by delta.
	//
	// delta can be positive or negative. If the ref-count becomes 0
	// or less, then the key SHOULD BE collected.
	UpdateRefCount(key Key, delta int) error
}

BlobStore is a simple CAS store used to save messages body and other information that is usually searched by a key.

Reference counting is used to identify unused data. When a refcount reaches 0 the data don't need to be collected. Calls to Get MIGHT return the old value until the data is collected and this isn't considered a error.

type Key

type Key interface {
	// Bytes should return the contents of the key
	Bytes() []byte
}

Key is used to identify a value inside the BlobStore

type KeyPrinter

type KeyPrinter struct{}

KeyPrinter is used to print any key to a human readable format, and parsing it back.

The format used is hex.Encode/hex.Decode

func (KeyPrinter) EncodedSize

func (kp KeyPrinter) EncodedSize(k Key) int

EncodedSize return the size required to output k using this printer

func (KeyPrinter) Grow

func (kp KeyPrinter) Grow(old []byte, k Key) []byte

Grow will return an slice that is large enough to hold the encoded key.

If old have enough space (cap(old) > kp.EncodedSize(k)) then no allocation is done

func (KeyPrinter) Print

func (kp KeyPrinter) Print(out []byte, k Key) []byte

Print will return the encoded value of k, if out is large enough no allocation is made.

It is valid to pass nil as out

func (KeyPrinter) PrintString

func (kp KeyPrinter) PrintString(k Key) string

String return the string representation of the value

func (KeyPrinter) Read

func (kp KeyPrinter) Read(out Key, in []byte) (err error)

Read will decode in to out, out should be large enough to hold the decoded length of in. If this isn't true ErrKeyTooShort is returned

If len(in) != kp.EncodedSize(out) then an error is returned, it is invalid to pass nil as out.

func (KeyPrinter) ReadString

func (kp KeyPrinter) ReadString(out Key, in string) (err error)

ReadString works just like Read but expects a string

type KeyWriter

type KeyWriter interface {
	io.Writer
	// Key should return the Key calculated from the data
	// passed via Write.
	Key() Key
}

KeyWriter is used to calculate keys from a given value

type Message

type Message struct {
	// Mid is the id of the message, calculated based on the
	// body of the message
	Mid Key
	// Lid is the id of the current associated lock
	Lid Key
	// Status holds the ack status of this message
	Status AckStatus
	// LeaseUntil holds the time when the Lid will become invalid
	LeasedUntil time.Time
	// FetchTime holds the time at the server when the message was requested by the client.
	FetchTime time.Time
	// ReceivedAt holds the server time when the message was received
	ReceivedAt time.Time
	// SendWhen is used to store when the message should be delivered. This is the ReceivedAt + Delay
	SendWhen time.Time
	// Delay is the time to wait before sending the message
	Delay time.Duration
	// DeliveryCount count how many times the message were delivered to a client.
	//
	// Only one client can access the message at any given time, but when the client crashes
	// or don't complete the message, then another client might access the message.
	DeliveryCount int
	// Body is a list of urlencoded data
	Body url.Values
	// contains filtered or unexported fields
}

Message is the header used to index the message

func (*Message) CalcualteLeaseFor

func (m *Message) CalcualteLeaseFor(now time.Time, lease time.Duration)

func (*Message) CalculateMid

func (m *Message) CalculateMid()

func (*Message) ClientTime

func (m *Message) ClientTime() time.Time

func (*Message) Empty

func (m *Message) Empty(body url.Values) *Message

Empty will clean all fields of this message and mark the message as if it was sent now

No sender or receiver is configured

func (*Message) Get

func (m *Message) Get(key string) string

func (*Message) Receiver

func (m *Message) Receiver() string

func (*Message) Sender

func (m *Message) Sender() string

func (*Message) Set

func (m *Message) Set(key, value string)

func (*Message) SetClientTime

func (m *Message) SetClientTime(ct time.Time)

func (*Message) SetReceiver

func (m *Message) SetReceiver(recv string)

func (*Message) SetSender

func (m *Message) SetSender(sender string)

func (*Message) ValidBody

func (m *Message) ValidBody() bool

func (*Message) WriteTo

func (m *Message) WriteTo(out url.Values)

type MessageStore

type MessageStore interface {
	// Enqueue will put msg in the outputbox of the receiver
	Enqueue(msg *Message) error

	// FetchAndLockLatest will fetch the next pending queue that is available for delivery, ie,
	// messages that aren't locked and the SendWhen is less than the current time.
	//
	// This also returns the Lid to be used with the message
	FetchAndLockLatest(receiver string, leaseTime time.Duration) (*Message, error)

	// Ack will change the status of the given mid message, only if lid is still valid
	Ack(mid, lid Key, status AckStatus) error

	// FetchHeaders fetch at least len(out) messages that have the given receiver
	// and were received after serverTime.
	//
	// Only pending messages are returned
	FetchHeaders(out []Message, receiver string, serverTime time.Time) (int, error)

	// Reenqueue messages considering now
	Reenqueue(now time.Time) error
}

MessageStore defines the required interface to allow the system to work

type SHA1Key

type SHA1Key [20]byte

SHA1Key store a sha1 hash as the key

func (*SHA1Key) Bytes

func (s *SHA1Key) Bytes() []byte

Bytes return the slice holding all 20 bytes of the hash

type SHA1KeyWriter

type SHA1KeyWriter struct {
	// contains filtered or unexported fields
}

Type used to calculate the value of a SHA1Key

func (*SHA1KeyWriter) Key

func (s *SHA1KeyWriter) Key() Key

Key will return the updated hash, if no write were made the key will be a 0 byte array

func (*SHA1KeyWriter) Write

func (s *SHA1KeyWriter) Write(b []byte) (int, error)

Write update the sha1 hash with b bytes

type Server

type Server struct {
	BlobStore    BlobStore
	MessageStore MessageStore
}

Server implements the pandora message API

func (*Server) Ack

func (s *Server) Ack(mid, lockId Key, ack AckStatus) error

Ack is used to confirm that a message mid was processed o rejected by the client.

func (*Server) FetchHeaders

func (s *Server) FetchHeaders(out []Message, receiver string, receivedAt time.Time) (int, error)

FetchHeaders output at least len(out) messages headers, no body is returned

func (*Server) FetchLatest

func (s *Server) FetchLatest(receiver string, lease time.Duration) (*Message, error)

FetchLatest fetch the latest message for the given receiver, it is possible to fetch the message and not the body (BlobStore is down), when that happens the client can check if the body is valid by calling Message.ValidBody.

If no error is returned, then the body is valid and there is no need to check that

func (*Server) Send

func (s *Server) Send(sender, receiver string, delay time.Duration, clientTime time.Time, body url.Values) (Message, error)

Send is used to send the givem message contents from sender to receiver, sendAt can be used to inform a duration and delay the actual delivery of the message.

delay will always be calculated by the server time.

The message body might be changed by the server by adding headers to it

func (*Server) WriteBlob

func (s *Server) WriteBlob(msg *Message) error

WriteBlob save the body of the message to the blobstore and writes the value back to msg.Mid

Directories

Path Synopsis
Http package allow the user to expose a a Pandora Server as a http server No authentication is done here.
Http package allow the user to expose a a Pandora Server as a http server No authentication is done here.
pandora is a reference client for the pandora server This client uses a http client to access the message store
pandora is a reference client for the pandora server This client uses a http client to access the message store
webui is a simple http user interface for pandora server
webui is a simple http user interface for pandora server

Jump to

Keyboard shortcuts

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