types

package
v1.9.4 Latest Latest
Warning

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

Go to latest
Published: Dec 7, 2021 License: MIT Imports: 7 Imported by: 7

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrDuplicateSubs = errors.New("duplicate subscriber")
	ErrNoSubs        = errors.New("subscriber does not exist")
	ErrNoData        = errors.New("no data in message")
	ErrBadParser     = errors.New("bad parser")

	DefaultSubsChSize = 10
)
View Source
var (
	// ErrReplicaStoreFull is returned when more than the intended number of replicas register with the scheduler tool
	ErrReplicaStoreFull = errors.New("replica store is full")
)

Functions

This section is empty.

Types

type AnnotatedEventDAG added in v1.9.3

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

func NewAnnotatedEventDag added in v1.9.3

func NewAnnotatedEventDag(d *EventDAG) *AnnotatedEventDAG

func (*AnnotatedEventDAG) AddEvent added in v1.9.3

func (a *AnnotatedEventDAG) AddEvent(e *Event, parents []*Event)

func (*AnnotatedEventDAG) Check added in v1.9.3

func (a *AnnotatedEventDAG) Check() bool

func (*AnnotatedEventDAG) SetFrameOfReference added in v1.9.3

func (a *AnnotatedEventDAG) SetFrameOfReference(e *Event) bool

type BaseService added in v1.0.2

type BaseService struct {
	Logger *log.Logger
	// contains filtered or unexported fields
}

BaseService provides the basic nuts an bolts needed to implement a service

func NewBaseService added in v1.0.2

func NewBaseService(name string, parentLogger *log.Logger) *BaseService

NewBaseService instantiates BaseService

func (*BaseService) Name added in v1.0.2

func (b *BaseService) Name() string

Name returns the name of the service

func (*BaseService) QuitCh added in v1.0.2

func (b *BaseService) QuitCh() <-chan struct{}

QuitCh returns the quit channel which will be closed when the service stops running

func (*BaseService) Running added in v1.0.2

func (b *BaseService) Running() bool

Running returns the flag

func (*BaseService) StartRunning added in v1.0.2

func (b *BaseService) StartRunning()

StartRunning is called to set the running flag

func (*BaseService) StopRunning added in v1.0.2

func (b *BaseService) StopRunning()

StopRunning is called to unset the running flag

type ClockValue added in v1.9.3

type ClockValue []float64

func (ClockValue) Eq added in v1.9.3

func (c ClockValue) Eq(other ClockValue) bool

func (ClockValue) Lt added in v1.9.3

func (c ClockValue) Lt(other ClockValue) bool

type Clonable

type Clonable interface {
	Clone() Clonable
}

Clonable is any type which returns a copy of itself on Clone()

type Event

type Event struct {
	// Replica at which the event occurs
	Replica ReplicaID `json:"replica"`
	// Type of the event
	Type EventType `json:"-"`
	// TypeS is the string representation of the event
	TypeS string `json:"type"`
	// ID unique identifier assigned for every new event
	ID uint64 `json:"id"`
	// Timestamp of the event
	Timestamp int64 `json:"timestamp"`
	// Vector clock value of the event
	ClockValue ClockValue
}

Event is a generic event that occurs at a replica

func NewEvent

func NewEvent(replica ReplicaID, t EventType, ts string, id uint64, time int64) *Event

func (*Event) Clone

func (e *Event) Clone() Clonable

Clone implements Clonable

func (*Event) IsMessageReceive added in v1.9.0

func (e *Event) IsMessageReceive() bool

func (*Event) IsMessageSend added in v1.9.0

func (e *Event) IsMessageSend() bool

func (*Event) IsTimeoutEnd added in v1.9.2

func (e *Event) IsTimeoutEnd() bool

func (*Event) IsTimeoutStart added in v1.9.2

func (e *Event) IsTimeoutStart() bool

func (*Event) Lt added in v1.9.3

func (e *Event) Lt(other *Event) bool

Returns true if the current event is less than `other`

func (*Event) MessageID added in v1.0.0

func (e *Event) MessageID() (string, bool)

func (*Event) Timeout added in v1.9.2

func (e *Event) Timeout() (*ReplicaTimeout, bool)

type EventDAG added in v1.0.2

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

func NewEventDag added in v1.0.2

func NewEventDag() *EventDAG

func (*EventDAG) AddDirty added in v1.9.3

func (d *EventDAG) AddDirty(e *Event, parents []*Event)

func (*EventDAG) AddNode added in v1.0.2

func (d *EventDAG) AddNode(e *Event, parents []*Event)

func (*EventDAG) Clean added in v1.9.2

func (d *EventDAG) Clean()

func (*EventDAG) Clone added in v1.9.3

func (d *EventDAG) Clone() *EventDAG

func (*EventDAG) GetLatestNode added in v1.9.3

func (d *EventDAG) GetLatestNode(e *Event) (*Event, bool)

func (*EventDAG) GetNode added in v1.9.3

func (d *EventDAG) GetNode(eid uint64) (*EventNode, bool)

func (*EventDAG) GetReceiveNode added in v1.9.3

func (d *EventDAG) GetReceiveNode(e *Event) (*Event, bool)

func (*EventDAG) GetSendNode added in v1.9.3

func (d *EventDAG) GetSendNode(e *Event) (*Event, bool)

func (*EventDAG) GetTimeoutEnd added in v1.9.3

func (d *EventDAG) GetTimeoutEnd(e *Event) (*Event, bool)

func (*EventDAG) GetTimeoutStart added in v1.9.3

func (d *EventDAG) GetTimeoutStart(e *Event) (*Event, bool)

func (*EventDAG) MarshalJSON added in v1.9.0

func (d *EventDAG) MarshalJSON() ([]byte, error)

type EventNode added in v1.0.2

type EventNode struct {
	Event *Event `json:"event"`

	Parents  *EventNodeSet `json:"parents"`
	Children *EventNodeSet `json:"children"`
	// contains filtered or unexported fields
}

func NewEventNode added in v1.0.2

func NewEventNode(e *Event) *EventNode

func (*EventNode) AddParents added in v1.0.2

func (n *EventNode) AddParents(parents []*EventNode)

func (*EventNode) Clone added in v1.9.3

func (n *EventNode) Clone() *EventNode

func (*EventNode) GetNext added in v1.9.0

func (n *EventNode) GetNext() uint64

func (*EventNode) GetPrev added in v1.9.0

func (n *EventNode) GetPrev() uint64

func (*EventNode) IsDirty added in v1.9.3

func (n *EventNode) IsDirty() bool

func (*EventNode) MarkClean added in v1.9.2

func (n *EventNode) MarkClean()

func (*EventNode) MarkDirty added in v1.9.2

func (n *EventNode) MarkDirty()

func (*EventNode) SetNext added in v1.0.2

func (n *EventNode) SetNext(next uint64)

func (*EventNode) SetPrev added in v1.0.2

func (n *EventNode) SetPrev(prev uint64)

type EventNodeSet added in v1.0.2

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

func NewEventNodeSet added in v1.0.2

func NewEventNodeSet() *EventNodeSet

func (*EventNodeSet) Add added in v1.0.2

func (d *EventNodeSet) Add(nid uint64)

func (*EventNodeSet) Clone added in v1.9.3

func (d *EventNodeSet) Clone() *EventNodeSet

func (*EventNodeSet) Exists added in v1.9.3

func (d *EventNodeSet) Exists(nid uint64) bool

func (*EventNodeSet) Iter added in v1.0.2

func (d *EventNodeSet) Iter() []uint64

func (*EventNodeSet) MarshalJSON added in v1.9.0

func (d *EventNodeSet) MarshalJSON() ([]byte, error)

func (*EventNodeSet) Size added in v1.9.0

func (d *EventNodeSet) Size() int

type EventNodeTag added in v1.9.3

type EventNodeTag struct {
	Event *Event
	Type  EventNodeTagType
	Min   *IntW
	Max   *IntW
}

func NewEventNodeTag added in v1.9.3

func NewEventNodeTag(e *Event) *EventNodeTag

type EventNodeTagType added in v1.9.3

type EventNodeTagType = string
var (
	MessageSend    EventNodeTagType = "MessageSend"
	MessageReceive EventNodeTagType = "MessageReceive"
	TimeoutStart   EventNodeTagType = "TimeoutStart"
	TimeoutEnd     EventNodeTagType = "TimeoutEnd"
	Other          EventNodeTagType = "Other"
)

type EventQueue added in v1.0.2

type EventQueue struct {
	*BaseService
	// contains filtered or unexported fields
}

EventQueue datastructure to store the messages in a FIFO queue

func NewEventQueue added in v1.0.2

func NewEventQueue(logger *log.Logger) *EventQueue

NewEventQueue returns an empty EventQueue

func (*EventQueue) Add added in v1.0.2

func (q *EventQueue) Add(m *Event)

Add adds a message to the queue

func (*EventQueue) Flush added in v1.0.2

func (q *EventQueue) Flush()

Flush clears the queue of all messages

func (*EventQueue) Restart added in v1.0.2

func (q *EventQueue) Restart() error

Restart implements Service

func (*EventQueue) Start added in v1.0.2

func (q *EventQueue) Start() error

Start implements Service

func (*EventQueue) Stop added in v1.0.2

func (q *EventQueue) Stop() error

Stop implements Service

func (*EventQueue) Subscribe added in v1.0.2

func (q *EventQueue) Subscribe(label string) chan *Event

Subscribe creates and returns a channel for the subscriber with the given label

type EventType

type EventType interface {
	// Clone copies the event type
	Clone() EventType
	// Type is a unique key for that event type
	Type() string
	// String should return a string representation of the event type
	String() string
}

EventType abstract type for representing different types of events

type GenericEventType added in v1.0.2

type GenericEventType struct {
	// Marshalled parameters
	Params map[string]string `json:"params"`
	// Type of event for reference
	// Eg: Commit
	T string `json:"type"`
}

GenericEventType is the event type published by a replica It can be specific to the algorithm that is implemented

func NewGenericEventType added in v1.0.2

func NewGenericEventType(params map[string]string, t string) *GenericEventType

NewGenericEventType instantiates GenericEventType

func (*GenericEventType) Clone added in v1.0.2

func (g *GenericEventType) Clone() EventType

Clone returns a copy of the current GenericEventType

func (*GenericEventType) String added in v1.0.2

func (g *GenericEventType) String() string

String returns a string representation of the event type

func (*GenericEventType) Type added in v1.0.2

func (g *GenericEventType) Type() string

Type returns a unique key for GenericEventType

type GlobalClock added in v1.9.3

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

func NewGlobalClock added in v1.9.3

func NewGlobalClock(dag *EventDAG, messageStore *MessageStore) *GlobalClock

type IntW added in v1.9.3

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

func NewIntW added in v1.9.3

func NewIntW() *IntW

func (*IntW) Set added in v1.9.3

func (i *IntW) Set(v int)

func (*IntW) Undefined added in v1.9.3

func (i *IntW) Undefined() bool

type Message

type Message struct {
	From          ReplicaID     `json:"from"`
	To            ReplicaID     `json:"to"`
	Data          []byte        `json:"data"`
	Type          string        `json:"type"`
	ID            string        `json:"id"`
	Intercept     bool          `json:"intercept"`
	ParsedMessage ParsedMessage `json:"-"`
	Repr          string        `json:"repr"`
}

Message stores a message that has been interecepted between two replicas

func (*Message) Clone

func (m *Message) Clone() Clonable

Clone to create a new Message object with the same attributes

func (*Message) Parse added in v1.9.4

func (m *Message) Parse(parser MessageParser) error

type MessageParser added in v1.9.4

type MessageParser interface {
	Parse([]byte) (ParsedMessage, error)
}

type MessageQueue added in v1.0.2

type MessageQueue struct {
	*BaseService
	// contains filtered or unexported fields
}

MessageQueue datastructure to store the messages in a FIFO queue

func NewMessageQueue added in v1.0.2

func NewMessageQueue(logger *log.Logger) *MessageQueue

NewMessageQueue returens an emtpy MessageQueue

func (*MessageQueue) Add added in v1.0.2

func (q *MessageQueue) Add(m *Message)

Add adds a message to the queue

func (*MessageQueue) Disable added in v1.0.4

func (q *MessageQueue) Disable()

Disable closes the queue and drops all incoming messages Use with caution

func (*MessageQueue) Enable added in v1.0.4

func (q *MessageQueue) Enable()

Enable enqueues the messages and feeds it to the subscribers if any

func (*MessageQueue) Flush added in v1.0.2

func (q *MessageQueue) Flush()

Flush clears the queue of all messages

func (*MessageQueue) Restart added in v1.0.2

func (q *MessageQueue) Restart() error

Restart implements Service

func (*MessageQueue) Start added in v1.0.2

func (q *MessageQueue) Start() error

Start implements Service

func (*MessageQueue) Stop added in v1.0.2

func (q *MessageQueue) Stop() error

Stop implements Service

func (*MessageQueue) Subscribe added in v1.0.2

func (q *MessageQueue) Subscribe(label string) chan *Message

Subscribe create and returns a channel for the subscriber with the specified label

type MessageReceiveEventType added in v1.0.2

type MessageReceiveEventType struct {
	// MessageID is the ID of the message received
	MessageID string
}

MessageReceiveEventType is the event type when a replica receives a message

func NewMessageReceiveEventType added in v1.0.2

func NewMessageReceiveEventType(messageID string) *MessageReceiveEventType

NewMessageReceiveEventType instantiates MessageReceiveEventType

func (*MessageReceiveEventType) Clone added in v1.0.2

Clone returns a copy of the current MessageReceiveEventType

func (*MessageReceiveEventType) String added in v1.0.2

func (r *MessageReceiveEventType) String() string

String returns a string representation of the event type

func (*MessageReceiveEventType) Type added in v1.0.2

func (r *MessageReceiveEventType) Type() string

Type returns a unique key for MessageReceiveEventType

type MessageSendEventType added in v1.0.2

type MessageSendEventType struct {
	// MessageID of the message that was sent
	MessageID string
}

MessageSendEventType is the event type where a message is sent from the replica

func NewMessageSendEventType added in v1.0.2

func NewMessageSendEventType(messageID string) *MessageSendEventType

NewMessageSendEventType instantiates MessageSendEventType

func (*MessageSendEventType) Clone added in v1.0.2

func (s *MessageSendEventType) Clone() EventType

Clone returns a copy of the current MessageSendEventType

func (*MessageSendEventType) String added in v1.0.2

func (s *MessageSendEventType) String() string

String returns a string representation of the event type

func (*MessageSendEventType) Type added in v1.0.2

func (s *MessageSendEventType) Type() string

Type returns a unique key for MessageSendEventType

type MessageStore added in v1.0.2

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

MessageStore to store the messages. Thread safe

func NewMessageStore added in v1.0.2

func NewMessageStore() *MessageStore

NewMessageStore creates a empty MessageStore

func (*MessageStore) Add added in v1.0.2

func (s *MessageStore) Add(m *Message) *Message

Add adds a message to the store Returns any old message with the same ID if it exists or nil if not

func (*MessageStore) Exists added in v1.0.2

func (s *MessageStore) Exists(id string) bool

Exists returns true if the message exists

func (*MessageStore) Get added in v1.0.2

func (s *MessageStore) Get(id string) (*Message, bool)

Get returns a message and bool indicating if the message exists

func (*MessageStore) Iter added in v1.9.0

func (s *MessageStore) Iter() []*Message

Iter returns a list of all the messages in the store

func (*MessageStore) Remove added in v1.9.0

func (s *MessageStore) Remove(id string) *Message

Remove returns and deleted the message from the store if it exists. Returns nil otherwise

func (*MessageStore) RemoveAll added in v1.9.0

func (s *MessageStore) RemoveAll()

RemoveAll empties the message store

func (*MessageStore) Size added in v1.9.0

func (s *MessageStore) Size() int

Size returns the size of the message store

type ParsedMessage added in v1.9.4

type ParsedMessage interface {
	String() string
	Clone() ParsedMessage
	Marshal() ([]byte, error)
}

type Replica

type Replica struct {
	ID    ReplicaID              `json:"id"`
	Ready bool                   `json:"ready"`
	Info  map[string]interface{} `json:"info"`
	Addr  string                 `json:"addr"`
}

Replica immutable representation of the attributes of a replica

type ReplicaID

type ReplicaID string

ReplicaID is an identifier for the replica encoded as a string

type ReplicaLog

type ReplicaLog struct {
	// Params is a marhsalled params of the log message
	Params map[string]string `json:"params"`
	// Message is the message that was logged
	Message string `json:"message"`
	// Timestamp of the log
	Timestamp int64 `json:"timestamp"`
	// Replica which posted the log
	Replica ReplicaID `json:"replica"`
}

ReplicaLog encapsulates a log message with the necessary attributes

func (*ReplicaLog) Clone

func (l *ReplicaLog) Clone() Clonable

Clone implements Clonable

type ReplicaLogQueue added in v1.0.4

type ReplicaLogQueue struct {
	*BaseService
	// contains filtered or unexported fields
}

ReplicaLogQueue is the queue of log messages

func NewReplicaLogQueue added in v1.0.4

func NewReplicaLogQueue(logger *log.Logger) *ReplicaLogQueue

NewReplicaLogQueue instantiates ReplicaLogQueue

func (*ReplicaLogQueue) Add added in v1.0.4

func (q *ReplicaLogQueue) Add(log *ReplicaLog)

Add adds to the queue

func (*ReplicaLogQueue) Flush added in v1.0.4

func (q *ReplicaLogQueue) Flush()

Flush erases the contents of the queue

func (*ReplicaLogQueue) Start added in v1.0.4

func (q *ReplicaLogQueue) Start()

Start implements Service

func (*ReplicaLogQueue) Stop added in v1.0.4

func (q *ReplicaLogQueue) Stop()

Stop implements Service

func (*ReplicaLogQueue) Subscribe added in v1.0.4

func (q *ReplicaLogQueue) Subscribe(label string) chan *ReplicaLog

Subscribe creates and returns a channel for the subscriber

type ReplicaLogStore added in v1.0.2

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

ReplicaLogStore stores the logs as a map indexed by the replica ID

func NewReplicaLogStore added in v1.0.2

func NewReplicaLogStore() *ReplicaLogStore

NewReplicaLogStore instantiates a ReplicaLogStore

func (*ReplicaLogStore) Add added in v1.0.4

func (store *ReplicaLogStore) Add(log *ReplicaLog)

Add adds to the log store

func (*ReplicaLogStore) GetLogs added in v1.0.4

func (store *ReplicaLogStore) GetLogs(replica ReplicaID, from, to int) ([]*ReplicaLog, int)

GetLogs returns the list of logs for a replica where from <=index<to

func (*ReplicaLogStore) Reset added in v1.9.0

func (store *ReplicaLogStore) Reset()

type ReplicaState added in v1.0.2

type ReplicaState struct {
	State     string    `json:"state"`
	Timestamp int64     `json:"timestamp"`
	Replica   ReplicaID `json:"replica"`
}

type ReplicaStateStore added in v1.0.2

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

func NewReplicaStateStore added in v1.0.2

func NewReplicaStateStore() *ReplicaStateStore

type ReplicaStore

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

ReplicaStore to store all replica information, thread safe

func NewReplicaStore

func NewReplicaStore(size int) *ReplicaStore

NewReplicaStore creates an empty ReplicaStore

func (*ReplicaStore) Add added in v1.0.2

func (s *ReplicaStore) Add(p *Replica)

Add adds or updates a replica to the store

func (*ReplicaStore) Cap added in v1.0.5

func (s *ReplicaStore) Cap() int

func (*ReplicaStore) Count

func (s *ReplicaStore) Count() int

Count returns the total number of replicas

func (*ReplicaStore) Get added in v1.0.2

func (s *ReplicaStore) Get(id ReplicaID) (p *Replica, ok bool)

Get returns the replica and a bool indicating if it exists or not

func (*ReplicaStore) Iter

func (s *ReplicaStore) Iter() []*Replica

Iter returns a list of the existing replicas

func (*ReplicaStore) NumReady

func (s *ReplicaStore) NumReady() int

NumReady returns the number of replicas with Ready attribute set to true

func (*ReplicaStore) ResetReady

func (s *ReplicaStore) ResetReady()

ResetReady sets the Ready attribute of all replicas to false

type ReplicaTimeout added in v1.0.2

type ReplicaTimeout struct {
	Replica  ReplicaID     `json:"replica"`
	Type     string        `json:"type"`
	Duration time.Duration `json:"duration"`
}

func TimeoutFromParams added in v1.9.2

func TimeoutFromParams(replica ReplicaID, params map[string]string) (*ReplicaTimeout, bool)

func (*ReplicaTimeout) Eq added in v1.9.3

func (t *ReplicaTimeout) Eq(other *ReplicaTimeout) bool

func (*ReplicaTimeout) MarshalJSON added in v1.9.2

func (t *ReplicaTimeout) MarshalJSON() ([]byte, error)

type RestartableService added in v1.0.2

type RestartableService interface {
	Service
	// Restart restarts the service
	Restart() error
}

RestartableService is a service which can be restarted

type Service added in v1.0.2

type Service interface {
	// Name of the service
	Name() string
	// Start to start the service
	Start() error
	// Running to indicate if the service is running
	Running() bool
	// Stop to stop the service
	Stop() error
	// Quit returns a channel which will be closed once the service stops running
	QuitCh() <-chan struct{}
}

Service is any entity which runs on a separate thread

type Subscriber added in v1.0.2

type Subscriber struct {
	Ch chan interface{}
}

Generic subscriber to maintain state of the subsciber

type TimeoutContext added in v1.9.2

type TimeoutContext struct {
	PendingTimeouts map[string]*timeoutWrapper
	PendingReceives map[string]*Event
	// contains filtered or unexported fields
}

func NewTimeoutContext added in v1.9.2

func NewTimeoutContext(d *EventDAG) *TimeoutContext

func (*TimeoutContext) AddEvent added in v1.9.2

func (t *TimeoutContext) AddEvent(e *Event)

func (*TimeoutContext) CanDeliverMessages added in v1.9.2

func (t *TimeoutContext) CanDeliverMessages(messages []*Message)

type TimeoutEndEventType added in v1.0.2

type TimeoutEndEventType struct {
	Timeout *ReplicaTimeout
}

func NewTimeoutEndEventType added in v1.0.2

func NewTimeoutEndEventType(timeout *ReplicaTimeout) *TimeoutEndEventType

func (*TimeoutEndEventType) Clone added in v1.0.2

func (te *TimeoutEndEventType) Clone() EventType

func (*TimeoutEndEventType) String added in v1.0.2

func (te *TimeoutEndEventType) String() string

func (*TimeoutEndEventType) Type added in v1.0.2

func (te *TimeoutEndEventType) Type() string

type TimeoutStartEventType added in v1.0.2

type TimeoutStartEventType struct {
	Timeout *ReplicaTimeout
}

func NewTimeoutStartEventType added in v1.0.2

func NewTimeoutStartEventType(timeout *ReplicaTimeout) *TimeoutStartEventType

func (*TimeoutStartEventType) Clone added in v1.0.2

func (ts *TimeoutStartEventType) Clone() EventType

func (*TimeoutStartEventType) String added in v1.0.2

func (ts *TimeoutStartEventType) String() string

func (*TimeoutStartEventType) Type added in v1.0.2

func (ts *TimeoutStartEventType) Type() string

type TimeoutStore added in v1.9.2

type TimeoutStore struct {
	*BaseService
	// contains filtered or unexported fields
}

func NewTimeoutStore added in v1.9.2

func NewTimeoutStore(logger *log.Logger) *TimeoutStore

func (*TimeoutStore) AddTimeout added in v1.9.2

func (s *TimeoutStore) AddTimeout(t *ReplicaTimeout)

func (*TimeoutStore) Reset added in v1.9.2

func (s *TimeoutStore) Reset()

func (*TimeoutStore) Start added in v1.9.2

func (s *TimeoutStore) Start() error

func (*TimeoutStore) Stop added in v1.9.2

func (s *TimeoutStore) Stop() error

func (*TimeoutStore) ToDispatch added in v1.9.2

func (s *TimeoutStore) ToDispatch() []*ReplicaTimeout

Jump to

Keyboard shortcuts

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