Class: ADAM6050::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/adam6050/session.rb

Overview

The session object is used by the server to keep track of authenticated clients. Once a client is registered with the session it will be reported as valid for a period of time, after which it is again marked as invalid and needs to register again. Any activity before the timeout will reset the countdown.

Usage

The following example creates a session with a 10 second timeout and registers a sender. ‘#validate!` is then called at a later point in time to verify that the sender is still valid.

session = Session.new timeout: 10.0
session.register sender

# The following call will raise an exception if more
# than 10 seconds has passed.
session.validate! sender

Defined Under Namespace

Classes: InvalidSender, UnknownSender

Constant Summary collapse

DEFAULT_TIMEOUT =

Returns the default number of seconds a sender is valid with no interaction.

Returns:

  • (Numeric)

    the default number of seconds a sender is valid with no interaction.

60.0
DEFAULT_CLEANUP_INTERVALL =

Returns the default number of seconds to wait after one cleanup before perfoming the next.

Returns:

  • (Numeric)

    the default number of seconds to wait after one cleanup before perfoming the next.

3600.0

Instance Method Summary collapse

Constructor Details

#initialize(timeout: DEFAULT_TIMEOUT, cleanup_interval: DEFAULT_CLEANUP_INTERVALL) ⇒ Session

Returns a new instance of Session.

Parameters:

  • timeout (Numeric) (defaults to: DEFAULT_TIMEOUT)

    the number of seconds a sender is valid with no interaction.

  • cleanup_interval (Numeric) (defaults to: DEFAULT_CLEANUP_INTERVALL)

    the number of seconds to wait after one cleanup before perfoming the next.



49
50
51
52
53
54
55
# File 'lib/adam6050/session.rb', line 49

def initialize(timeout: DEFAULT_TIMEOUT,
               cleanup_interval: DEFAULT_CLEANUP_INTERVALL)
  @session          = {}
  @timeout          = timeout
  @cleanup_interval = cleanup_interval
  @next_cleanup     = 0.0
end

Instance Method Details

#cleanup!(time: monotonic_timestamp) ⇒ Numeric

Removes invalid senders from the session.

Parameters:

  • time (Numeric) (defaults to: monotonic_timestamp)

    the current time. The current time will be used if not specified.

Returns:

  • (Numeric)

    the next time before which no cleanup will be performed.



112
113
114
115
116
117
118
# File 'lib/adam6050/session.rb', line 112

def cleanup!(time: monotonic_timestamp)
  return if time < @next_cleanup

  delete_expired! time, @timeout

  @next_cleanup = time + @cleanup_interval
end

#register(sender, time: monotonic_timestamp) ⇒ nil

Register a new sender as valid in the current session.

Parameters:

  • sender (Socket::UDPSource)

    the udp client.

  • time (Numeric) (defaults to: monotonic_timestamp)

    the current time. The current time will be used if not specified.

Returns:

  • (nil)


70
71
72
73
# File 'lib/adam6050/session.rb', line 70

def register(sender, time: monotonic_timestamp)
  @session[session_key sender] = time
  nil
end

#sizeInteger

Returns the number of senders currently known by the session. Note that this may include invalid senders that have not yet been cleaned up.

Returns:

  • (Integer)

    the number of senders currently known by the session. Note that this may include invalid senders that have not yet been cleaned up.



60
61
62
# File 'lib/adam6050/session.rb', line 60

def size
  @session.size
end

#valid?(sender, time: monotonic_timestamp) ⇒ true, false

A sender is valid as long as it is registered and has not expired within the current session.

Parameters:

  • sender (Socket::UDPSource)

    the udp client.

  • time (Numeric) (defaults to: monotonic_timestamp)

    the current time. The current time will be used if not specified.

Returns:

  • (true)

    if the sender has authenticated and has been active within the configured timeout.

  • (false)

    otherwise.



84
85
86
# File 'lib/adam6050/session.rb', line 84

def valid?(sender, time: monotonic_timestamp)
  !expired? @session.fetch(session_key(sender), 0.0), time, @timeout
end

#validate!(sender, time: monotonic_timestamp) ⇒ nil

Renews the given sender if it is still valid within the session and raises an exception otherwise.

Parameters:

  • sender (Socket::UDPSource)

    the udp client.

  • time (Numeric) (defaults to: monotonic_timestamp)

    the current time. The current time will be used if not specified.

Returns:

  • (nil)

Raises:



98
99
100
101
102
103
104
105
# File 'lib/adam6050/session.rb', line 98

def validate!(sender, time: monotonic_timestamp)
  key = session_key sender
  last_observed = @session.fetch(key) { raise UnknownSender, sender }
  raise InvalidSender, sender if expired? last_observed, time, @timeout

  @session[key] = time
  nil
end