Class: SBSM::DRbServer

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

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.



45
46
47
48
49
50
51
52
53
# File 'lib/sbsm/drbserver.rb', line 45

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.



44
45
46
# File 'lib/sbsm/drbserver.rb', line 44

def cleaner
  @cleaner
end

#updaterObject (readonly)

Returns the value of attribute updater.



44
45
46
# File 'lib/sbsm/drbserver.rb', line 44

def updater
  @updater
end

Instance Method Details

#[](key) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/sbsm/drbserver.rb', line 148

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



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

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



79
80
81
# File 'lib/sbsm/drbserver.rb', line 79

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

#cap_max_sessions(now = Time.now) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/sbsm/drbserver.rb', line 82

def cap_max_sessions(now = Time.now)
	if(@sessions.size > self::class::CAP_MAX_THRESHOLD)
		puts "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)
        puts sprintf("deleted all sessions that had not been accessed for more than %im %is", age / 60, age % 60)
      end
	end
end

#cleanObject



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/sbsm/drbserver.rb', line 97

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)



118
119
120
121
# File 'lib/sbsm/drbserver.rb', line 118

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

#delete_session(key) ⇒ Object



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

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

#resetObject



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

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

#run_cleanerObject



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/sbsm/drbserver.rb', line 132

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



145
146
147
# File 'lib/sbsm/drbserver.rb', line 145

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