countdown

package module
v0.0.0-...-7de8c83 Latest Latest
Warning

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

Go to latest
Published: Feb 4, 2019 License: MIT Imports: 6 Imported by: 0

README

⏰ final-countdown

Simple service for managing countdown timers

Purpose

This library is intended to supplement applications that need to maintain timers, e.g. a web-based board game like GoStop.

Installation

go get github.com/camirmas/final-countdown

Usage

There are three main entities of note in this library:

  • Service, which is is a higher-level abstraction that can manage concurrent Timers
  • Timer, which runs a countdown sequence
  • Store, which is an interface for storing multiple timers. The default for a Service is BoltStore, which uses key/value database Bolt
Starting a Service
package main

import "github.com/camirmas/final-countdown"

service := Service{}

// The first argument is an optional `Store` implementation.
// If you do not want to supply your own, you must include an
// Options value.
service.Start(nil, Options{DbPath: "countdown.db"}) // is the same as service.Start(nil, Options{})
Manage Timers
package main

import "github.com/camirmas/final-countdown"

service := countdown.Service{}
service.Start(nil, countdown.Options{DbPath: "countdown.db"}) // is the same as service.Start(nil, countdown.Options{})

id := 1
duration := 10

timer, err := service.StartTimer(id, duration)

if err != nil {
  // handle err
}

if err := service.PauseTimer(id); err != nil {
  // handle err
}

if err := service.ResumeTimer(id); err != nil {
  // handle err
}

if err := service.CancelTimer(id); err != nil {
  // handle err
}
Interacting with a Timer

Now, the client wants to be notified of timer changes, and it uses a provided channel to do so:

timer, _ := service.GetTimer(id)

/// This will keep looping through the channel (chan int) until it closes
for tr := range timer.Channel() {
  // do stuff here
}

Here's the lifecycle of a managed Timer:

  1. created by a Service via StartTimer
  2. runs a countdown in a separate goroutine
  3. Either:
  • finishes its countdown, then notifies the parent Service, which deletes it
  • gets cancelled by the Service before it finishes the countdown

The intended behavior of a managed Timer is such that it should spin up once, then either get cancelled by the Service, or complete its countdown and tell the Service to destroy it.

Using a standalone Timer

While a Service is intended to handle most aspects of using Timers, especially many at a time, a Timer can still be run on its own. This can be used in a case where an application has its own way that it wishes to manage them, or simply doesn't need the extra overhead of a Service.

id := 1
duration := 3

// can optionally provide a Store here
timer := NewTimer(id, duration, nil)

// can optionally provide a chan int here, the Timer will send its Id to that channel upon countdown completion
timer.Start(nil)
timer.Pause()
timer.Resume()
timer.Cancel()
Using a different Store

The library supports using different backends to manage Timers. This can be achieved by simply implementing the following interface:

// General interface for storing Timer info. This allows for multiple backend
// implementations.
type Store interface {
	// ListTimers returns all timers
	ListTimers() []*Timer
	// AddTimer adds a new Timer to the store
	AddTimer(timer *Timer) error
	// GetTimer gets a timer by id
	GetTimer(id int) (*Timer, error)
	// UpdateTimer updates an existing Timer
	UpdateTimer(timer *Timer) error
	// Remove removes a Timer from the store
	RemoveTimer(id int) error
}

That implementation can then be passed into a new Service: service.Start(myStore, nil)

Documentation

Overview

The countdown package provides a simple service for managing countdown timers.

Index

Constants

View Source
const (
	Running   string = "running"
	Paused    string = "paused"
	Cancelled string = "cancelled"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type BoltStore

type BoltStore struct {
	*bolt.DB
}

func ConnectBoltStore

func ConnectBoltStore(filepath string) (*BoltStore, error)

func (BoltStore) AddTimer

func (db BoltStore) AddTimer(t *Timer) error

func (BoltStore) GetTimer

func (db BoltStore) GetTimer(id int) (*Timer, error)

func (BoltStore) ListTimers

func (db BoltStore) ListTimers() []*Timer

func (BoltStore) RemoveTimer

func (db BoltStore) RemoveTimer(id int) error

func (BoltStore) UpdateTimer

func (db BoltStore) UpdateTimer(t *Timer) error

type Options

type Options struct {
	DbPath string
}

Options for running the service

type Service

type Service struct {

	// Store options for running the Service
	Options *Options
	// contains filtered or unexported fields
}

The primary entry point for this library. It is responsible for maintaining the Timers and interacting with the client.

func (*Service) CancelTimer

func (s *Service) CancelTimer(id int) error

CancelTimer cancels an existing Timer if it exists.

func (*Service) GetTimer

func (s *Service) GetTimer(id int) (*Timer, error)

GetTimer retrieves an existing Timer. First it checks if there is a Timer in memory. Then it checks the DB, and if it finds one there, it sets up a new one because the old channels are gone.

func (*Service) PauseTimer

func (s *Service) PauseTimer(id int) error

PauseTimer temporarily pauses a Timer if it exists.

func (*Service) ResumeTimer

func (s *Service) ResumeTimer(id int) error

ResumeTimer temporarily pauses a Timer if it exists.

func (*Service) Start

func (s *Service) Start(store Store, options *Options) error

Start runs the service

func (*Service) StartTimer

func (s *Service) StartTimer(id, duration int) (*Timer, error)

StartTimer creates a new Timer for the Service, and Starts it.

type Store

type Store interface {
	// ListTimers returns all timers
	ListTimers() []*Timer
	// AddTimer adds a new Timer to the store
	AddTimer(timer *Timer) error
	// GetTimer gets a timer by id
	GetTimer(id int) (*Timer, error)
	// UpdateTimer updates an existing Timer
	UpdateTimer(timer *Timer) error
	// Remove removes a Timer from the store
	RemoveTimer(id int) error
}

General interface for storing Timer info. This allows for multiple backend implementations.

type Timer

type Timer struct {
	// A unique identifier
	Id int `json:"id"`
	// How long it should run
	Duration int `json:"duration"`
	// contains filtered or unexported fields
}

The timer can be expressed as a channel of Messages. The client will read from this channel to get updated time, and will send messages to it.

func NewTimer

func NewTimer(id, duration int, store Store) *Timer

func (*Timer) Cancel

func (t *Timer) Cancel() error

func (*Timer) Channel

func (t *Timer) Channel() chan int

Gets the timer channel

func (*Timer) Pause

func (t *Timer) Pause()

func (*Timer) Resume

func (t *Timer) Resume(service chan int)

func (*Timer) Start

func (t *Timer) Start(service chan int) error

func (*Timer) Status

func (t *Timer) Status() string

type TimerExistsError

type TimerExistsError struct{}

func (TimerExistsError) Error

func (e TimerExistsError) Error() string

type TimerNotFoundError

type TimerNotFoundError struct{}

func (TimerNotFoundError) Error

func (e TimerNotFoundError) Error() string

Jump to

Keyboard shortcuts

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