Giter Site home page Giter Site logo

dms's Introduction

DMS (Dead Man's Switch)

A simple OTP Application (and eventually an HTTP API) which enables short circuiting when a service becomes unavailable.

Used as a learning project for members of Belfast Elixir.

  • Build: mix do deps.get, compile
  • Test: mix test
  • Documentation: mix docs
  • REPL: iex -S mix
  • Observe: :observer.start

API Examples

# Ping will register service with that id as alive
id = "my-svc-id"
DMS.ping(id) # => :pong
DMS.alive?(id) # => true ~ Service with id responds as alive
# After @timeout period and no further pings
DMS.alive?(id) # => false ~ Service with id responds as dead
# An id which has never pinged will also respond as dead
false = DMS.alive?("another-svc-id") #=> false

Checklist

  • (#13) Model a Service as a Process (DMS.Service)
  • (#1) Register Service against an id (DMS.Servce.Registry)
  • (#2) Add a supervisor for Service Process (DMS.Service.Supervisor)
  • (#3) Add ping(id) function which will init Service if doesn't exist
  • (#4) Add alive?(id) function which returns true if service alive otherwise false
  • (#5) Add timer to service process which will terminate the process if it hasn't been pinged within @timeout
  • (#12) Add Documentation with ExDoc
  • (#6) Add Credo & Dialyzer for linting and static analysis.
  • (#7) Add API to set service as down (before timeout).
  • (#8) Enhance DMS.id to contain service id and account token + hash it before use as key in DMS.Servise.Registry.
  • (#9) Add HTTP API.
  • (#10) Add Pub/Sub push based API to notify when service is down.
  • (#11) Publish on HEX package manager.

dms's People

Contributors

cloggy45 avatar holsee avatar stephenfutrli avatar swmcc avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

mattcree denvera

dms's Issues

Fix race condition on Service initialisation

DMS/lib/dms/service.ex

Lines 25 to 35 in 1efe918

if exists?(id) do
GenServer.cast(via_registry(id), :ping)
:pong
else
child_spec = %{
id: id,
restart: :temporary,
start: {__MODULE__, :start_link, [id]}
}
{:ok, _} = DynamicSupervisor.start_child(@supervisor, child_spec)

This would result in a race condition when 2 attempts to start the same service happen at once.

This should be resolved by leveraging the return value of DynamicSupervisor.start_child/2 which is the following:

  {:ok, pid()}
  | :ignore
  | {:error, {:already_started, pid()} | {:shutdown, term()} | term()}

In particular the :already_started value sounds like a good option to resolve this: "If a process with the specified server name already exists, this function returns {:error, {:already_started, pid}} with the PID of that process."

However the processes are not named, and the Registry is being used, so we may need to explore the Registry functionality in order to find the correct solution.

Add in CI

We want this repo to have a CI flow. The CI should be executed when a new branch is pushed or a push to master occurs.

Don't forget to add the relevant buttons to the README.

Compiler Warnings Introduced

warning: unused import DMS.Service.Registry.whereis_name/1
  lib/dms/service.ex:8

Generated dms app
warning: unused import Task
  test/dms_test.exs:13

Slow Test on Kill Switch

The timer/kill switch signal is causing the test which verifies it to be too slow.

This will need to be extracted, mocked or configured in such a way that it can run much faster for the sake of not incurring long wait times within the unit tests.

Improve definition and validation of "Service.id()" parameter

During the last couple of meet-ups the topic of valid Service ids has came up.

The current constraints are as follows:

  • Any non-empty binary < 256 bytes.

The current thinking is that this will be improved to be:

  • Alpha-numeric.
  • Supports - and _.
  • Does not allow print characters or special characters.

Handle ping/1 function failure condition

DMS.ping/1 has a contract of returning :ping on the successful acknowledgement that service will return true when asked if alive for timeout period.

It also states it will return :pang when this is not the case when the DMS will not guarantee to signal alive to be true for the service. This condition is not implemented.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.