Class: SBSM::DRbServer

Inherits:
SimpleDelegator
  • Object
show all
Includes:
DRbUndumped
Defined in:
lib/sbsm/drbserver.rb

Direct Known Subclasses

App

Constant Summary collapse

CLEANING_INTERVAL =
30
CAP_MAX_THRESHOLD =
120
ENABLE_ADMIN =
false
MAX_SESSIONS =
100
RUN_CLEANER =
true
SESSION =
Session
UNKNOWN_USER =
UnknownUser
VALIDATOR =
nil

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(persistence_layer = nil) ⇒ DRbServer

Returns a new instance of DRbServer.



49
50
51
52
53
54
55
56
57
# File 'lib/sbsm/drbserver.rb', line 49

def initialize(persistence_layer=nil)
  @sessions = {}
  @mutex = Mutex.new
  @cleaner = run_cleaner if(self.class.const_get(:RUN_CLEANER))
  @admin_threads = ThreadGroup.new
  @async = ThreadGroup.new
  @system = persistence_layer
  super(persistence_layer)
end

Instance Attribute Details

#cleanerObject (readonly)

Returns the value of attribute cleaner.



48
49
50
# File 'lib/sbsm/drbserver.rb', line 48

def cleaner
  @cleaner
end

#updaterObject (readonly)

Returns the value of attribute updater.



48
49
50
# File 'lib/sbsm/drbserver.rb', line 48

def updater
  @updater
end

Instance Method Details

#[](key) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/sbsm/drbserver.rb', line 152

def [](key)
  @mutex.synchronize {
    unless((s = @sessions[key]) && !s.expired?)
      args = [key, self]
      if(klass = self::class::VALIDATOR)
        args.push(klass.new)
      end
      s = @sessions[key] = self::class::SESSION.new(*args.compact)
    end
    s.reset()
    s.touch()
    s
  }
end

#_admin(src, result, priority = 0) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/sbsm/drbserver.rb', line 58

def _admin(src, result, priority=0)
  raise "admin interface disabled" unless(self::class::ENABLE_ADMIN)
  t = Thread.new {
    Thread.current.abort_on_exception = false
    result << begin
      response = begin
        instance_eval(src)
      rescue NameError => e
        e
      end
      str = response.to_s
      if(str.length > 200)
        response.class
      else
        str
      end
    rescue StandardError => e
      e.message
    end.to_s
  }
  t[:source] = src
  t.priority = priority
  @admin_threads.add(t)
  t
end

#async(&block) ⇒ Object



83
84
85
# File 'lib/sbsm/drbserver.rb', line 83

def async(&block)
  @async.add(Thread.new(&block))
end

#cap_max_sessions(now = Time.now) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/sbsm/drbserver.rb', line 86

def cap_max_sessions(now = Time.now)
  if(@sessions.size > self::class::CAP_MAX_THRESHOLD)
    SBSM.info "too many sessions! Keeping only #{self::class::MAX_SESSIONS}"
      sess = nil
    sorted = @sessions.values.sort
    sorted[0...(-self::class::MAX_SESSIONS)].each { |sess|
      sess.__checkout
      @sessions.delete(sess.key)
    }
      if(sess)
        age = sess.age(now)
        SBSM.info sprintf("deleted all sessions that had not been accessed for more than %im %is", age / 60, age % 60)
      end
  end
end

#cleanObject



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/sbsm/drbserver.rb', line 101

def clean
    now = Time.now
  @sessions.delete_if { |key, s| 
      begin
        if s.respond_to?(:expired?)
          if s.expired?(now)
            s.__checkout
            true
          else
            s.cap_max_states
            false
          end
        else
          true
        end
      rescue
        true
      end
  }
  #cap_max_sessions(now)
end

#clearObject

cap_max_sessions(now)



122
123
124
125
# File 'lib/sbsm/drbserver.rb', line 122

def clear
  @sessions.each_value { |sess| sess.__checkout }
  @sessions.clear
end

#delete_session(key) ⇒ Object



126
127
128
129
130
# File 'lib/sbsm/drbserver.rb', line 126

def delete_session(key)
  if(sess = @sessions.delete(key))
    sess.__checkout
  end
end

#resetObject



131
132
133
134
135
# File 'lib/sbsm/drbserver.rb', line 131

def reset
  @mutex.synchronize {
    @sessions.clear
  }
end

#run_cleanerObject



136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/sbsm/drbserver.rb', line 136

def run_cleaner
  # puts "running cleaner thread"
  Thread.new {
    Thread.current.abort_on_exception = true
    #Thread.current.priority = 1
    loop {
      sleep self::class::CLEANING_INTERVAL
      @mutex.synchronize {
        clean()
      }
    }
  }
end

#unknown_userObject



149
150
151
# File 'lib/sbsm/drbserver.rb', line 149

def unknown_user
  self::class::UNKNOWN_USER.new
end