manqod-server 1.257.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/manqod-server +96 -0
- data/doc/HOWTO +8 -0
- data/doc/INSTALL +2 -0
- data/doc/LICENCE +450 -0
- data/doc/README +24 -0
- data/doc/gentoo/etc/conf.d/manqod-server +2 -0
- data/doc/gentoo/etc/init.d/manqod-server +32 -0
- data/doc/manqod.sql +440 -0
- data/doc/manqod_structure.sql +356 -0
- data/doc/server.conf.example +19 -0
- data/etc/update.sql +35 -0
- data/lib/DBSetup.rb +98 -0
- data/lib/DrbDB/Cron.rb +66 -0
- data/lib/DrbDB/DrbForm.rb +79 -0
- data/lib/DrbDB/DrbImages.rb +39 -0
- data/lib/DrbDB/DrbListModel.rb +671 -0
- data/lib/DrbDB/EventCache.rb +47 -0
- data/lib/DrbDB/GtkAttributes.rb +39 -0
- data/lib/DrbDB/Help.rb +47 -0
- data/lib/DrbDB/Messaging.rb +75 -0
- data/lib/DrbDB/MyMultiSQL/jdbc.rb +107 -0
- data/lib/DrbDB/MyMultiSQL/mysql-ruby.rb +114 -0
- data/lib/DrbDB/MyMultiSQL.rb +226 -0
- data/lib/DrbDB/Users.rb +61 -0
- data/lib/DrbDB.rb +274 -0
- data/lib/Eprint.rb +94 -0
- data/lib/HeartBeat.rb +54 -0
- data/lib/ManqodLogger.rb +27 -0
- data/lib/ManqodServer.rb +167 -0
- metadata +132 -0
data/lib/DrbDB/Users.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#this file is part of manqod
|
2
|
+
#manqod is distributed under the CDDL licence
|
3
|
+
#the owner of manqod is Dobai-Pataky Balint(dpblnt@gmail.com)
|
4
|
+
|
5
|
+
class Users
|
6
|
+
include Eprint
|
7
|
+
include DRbUndumped
|
8
|
+
def initialize(drbdb)
|
9
|
+
@drbdb=drbdb
|
10
|
+
@users=Hash.new
|
11
|
+
@groups=Hash.new
|
12
|
+
@usergroups=Hash.new
|
13
|
+
end
|
14
|
+
attr_reader :drbdb
|
15
|
+
|
16
|
+
def load_all
|
17
|
+
@users.clear
|
18
|
+
@groups.clear
|
19
|
+
@usergroups.clear
|
20
|
+
drbdb.admin.rows("select * from users").each{|row|
|
21
|
+
@users[row["id"].to_i]=row
|
22
|
+
}
|
23
|
+
einfo("#{@users.length} users\n")
|
24
|
+
drbdb.admin.rows("select * from groups").each{|row|
|
25
|
+
@groups[row["id"].to_i]=row
|
26
|
+
}
|
27
|
+
drbdb.admin.rows("select * from usergroups").each{|row|
|
28
|
+
@usergroups[row["id"].to_i]=row
|
29
|
+
}
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def user_in_group?(user_id,group_id)
|
34
|
+
found=false
|
35
|
+
@usergroups.each_value{|ugrp|
|
36
|
+
found=true if ugrp["userid"].to_i == user_id && ugrp["groupid"].to_i == group_id
|
37
|
+
}
|
38
|
+
found
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_user(user_id)
|
42
|
+
@users[user_id]
|
43
|
+
end
|
44
|
+
|
45
|
+
def each
|
46
|
+
@users.each_key{|im_key| yield im_key}
|
47
|
+
end
|
48
|
+
def auth?(nick,password)
|
49
|
+
found=false
|
50
|
+
@users.each{|key,user|
|
51
|
+
found=true if nick.to_s == user["nick"].to_s && user["passwd"].to_s == password.to_s
|
52
|
+
}
|
53
|
+
found
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
"Users of #{drbdb}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
data/lib/DrbDB.rb
ADDED
@@ -0,0 +1,274 @@
|
|
1
|
+
#this file is part of manqod
|
2
|
+
#manqod is distributed under the CDDL licence
|
3
|
+
#the author of manqod is Dobai-Pataky Balint(dpblnt@gmail.com)
|
4
|
+
|
5
|
+
class DrbDb
|
6
|
+
include Eprint
|
7
|
+
include DRbUndumped
|
8
|
+
include SQL
|
9
|
+
include Help
|
10
|
+
include Cron
|
11
|
+
include GtkAttributes
|
12
|
+
include EventCache
|
13
|
+
include Messaging
|
14
|
+
|
15
|
+
INIT=0
|
16
|
+
LOADING=1
|
17
|
+
SERVING=2
|
18
|
+
|
19
|
+
def initialize(connection,main_server_uri)
|
20
|
+
@state=INIT
|
21
|
+
@connection=connection
|
22
|
+
@main_server_uri=main_server_uri
|
23
|
+
@moditems=Hash.new #[moditem_id][id][fields]
|
24
|
+
@server=nil
|
25
|
+
# @relations=Hash.new
|
26
|
+
# @server=DRb::DRbServer.new(@connection['uri'],self)
|
27
|
+
end
|
28
|
+
attr_reader :uri, :moditems, :admin, :client, :cache, :connection, :images, :state
|
29
|
+
attr_accessor :server, :main_server
|
30
|
+
|
31
|
+
def init
|
32
|
+
einfo("Memcached #{Memcached::VERSION}")
|
33
|
+
@cache = Memcached.new([@connection['cache_host']],{:prefix_key=>key_name, :default_ttl => 0, :timeout => 2})
|
34
|
+
DRb.start_service(@connection["uri"],self)
|
35
|
+
@server=DRb.current_server()
|
36
|
+
@main_server=DRb::DRbObject.new_with_uri(@main_server_uri)
|
37
|
+
@uri=server.uri()
|
38
|
+
unless init_sql(@connection['sql_host'],@connection['sql_user'],@connection['sql_password'],@connection['sql_db'])
|
39
|
+
eerror("connection to sql server failed: #{@connection['sql_user']}@#{@connection['sql_host']}/#{@connection['sql_db']}")
|
40
|
+
return nil
|
41
|
+
end
|
42
|
+
update_manqod_db
|
43
|
+
begin
|
44
|
+
begin
|
45
|
+
@admin=DRb::DRbObject.new(nil,@connection['admin_uri'])
|
46
|
+
we_have_admin=@admin.alive?
|
47
|
+
rescue
|
48
|
+
ewarn("no admin?")
|
49
|
+
sleep 1
|
50
|
+
end
|
51
|
+
end until we_have_admin
|
52
|
+
begin
|
53
|
+
@state=LOADING
|
54
|
+
load_all_attributes
|
55
|
+
|
56
|
+
admin.rows("select moditems.id,modules.modname,moditems.display from moditems left join modules on modules.id = moditems.modid").each{|moditem|
|
57
|
+
begin
|
58
|
+
case moditem["modname"]
|
59
|
+
when "listing"
|
60
|
+
@moditems[moditem["id"].to_i]=DrbListModel.new(self,moditem["id"].to_i).create_skeleton unless @moditems.has_key?(moditem["id"])
|
61
|
+
@moditems[moditem["id"].to_i].update(self)
|
62
|
+
when "form"
|
63
|
+
@moditems[moditem["id"].to_i]=DrbForm.new(self,moditem["id"].to_i).create_skeleton unless @moditems.has_key?(moditem["id"])
|
64
|
+
else
|
65
|
+
ewarn("not caching #{moditem['display']}[#{moditem['modname']}]")
|
66
|
+
end
|
67
|
+
rescue =>err
|
68
|
+
ewarn("error loading moditem: #{moditem.inspect}")
|
69
|
+
eexception(err,:moditem => moditem)
|
70
|
+
end
|
71
|
+
}
|
72
|
+
@images=DrbImages.new(self).load_all
|
73
|
+
@users=Users.new(self).load_all
|
74
|
+
load_all_events
|
75
|
+
load_all_help
|
76
|
+
start_cron
|
77
|
+
@state=SERVING
|
78
|
+
rescue => err
|
79
|
+
eerror("failed to start: #{err}")
|
80
|
+
retry
|
81
|
+
end
|
82
|
+
|
83
|
+
DRb.thread.join
|
84
|
+
einfo("EXITED")
|
85
|
+
exit
|
86
|
+
end
|
87
|
+
|
88
|
+
def setup_client
|
89
|
+
if @connection['client_uri'].length>0
|
90
|
+
begin
|
91
|
+
@client=DRb::DRbObject.new(nil,@connection['client_uri'])
|
92
|
+
einfo("client is alive?(#{@client}): #{@client.alive?}")
|
93
|
+
rescue
|
94
|
+
@client=nil
|
95
|
+
einfo("no client.")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
def name
|
100
|
+
@connection['name']
|
101
|
+
end
|
102
|
+
def key_name
|
103
|
+
@connection['key_name']
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
def moditem(mod_id)
|
108
|
+
@moditems[mod_id.to_i]
|
109
|
+
end
|
110
|
+
|
111
|
+
def reload_moditem(moditem_id)
|
112
|
+
@state=LOADING
|
113
|
+
if moditem(moditem_id).nil?
|
114
|
+
einfo("creating moditem ##{moditem_id}")
|
115
|
+
#moditem added
|
116
|
+
admin.rows("select moditems.id,modules.modname,moditems.display
|
117
|
+
from moditems
|
118
|
+
left join modules on modules.id = moditems.modid
|
119
|
+
where moditems.id='#{moditem_id}'").each{|moditem|
|
120
|
+
begin
|
121
|
+
case moditem["modname"]
|
122
|
+
when "listing"
|
123
|
+
@moditems[moditem["id"].to_i]=DrbListModel.new(self,moditem["id"].to_i).create_skeleton unless @moditems.has_key?(moditem["id"])
|
124
|
+
@moditems[moditem["id"].to_i].update(self)
|
125
|
+
when "form"
|
126
|
+
@moditems[moditem["id"].to_i]=DrbForm.new(self,moditem["id"].to_i).create_skeleton unless @moditems.has_key?(moditem["id"])
|
127
|
+
else
|
128
|
+
eerror("not caching #{moditem['display']}[#{moditem['modname']}]")
|
129
|
+
end
|
130
|
+
rescue =>err
|
131
|
+
ewarn("error loading moditem: #{moditem.inspect}")
|
132
|
+
eexception(err,:moditem => moditem)
|
133
|
+
end
|
134
|
+
}
|
135
|
+
|
136
|
+
else
|
137
|
+
einfo("reloading moditem ##{moditem_id}")
|
138
|
+
case moditem(moditem_id).mod_type
|
139
|
+
when "list"
|
140
|
+
new_model=DrbListModel.new(self,moditem_id).create_skeleton
|
141
|
+
edebug("#{new_model} created")
|
142
|
+
new_model.update(self)
|
143
|
+
unless @moditems[moditem_id.to_i].nil?
|
144
|
+
@moditems[moditem_id.to_i].clients.each{|c| new_model.subscribe(c)}
|
145
|
+
edebug("#{@moditems[moditem_id.to_i]} abandoned")
|
146
|
+
end
|
147
|
+
@moditems[moditem_id.to_i]=new_model
|
148
|
+
@moditems[moditem_id.to_i].notify_clients(nil,"structure")
|
149
|
+
when "form"
|
150
|
+
moditem(moditem_id).create_skeleton
|
151
|
+
end
|
152
|
+
end
|
153
|
+
@state=SERVING
|
154
|
+
end
|
155
|
+
|
156
|
+
def reload_users
|
157
|
+
@users.load_all
|
158
|
+
end
|
159
|
+
|
160
|
+
def reload_client_images
|
161
|
+
main_server.connected_clients.each_pair{|cc,cdb|
|
162
|
+
if cdb == client.name
|
163
|
+
einfo("sending reload images to #{cc}")
|
164
|
+
cc.rpc("DrbImages.instance.load_images")
|
165
|
+
end
|
166
|
+
}
|
167
|
+
end
|
168
|
+
|
169
|
+
def reload_client_attributes
|
170
|
+
client.load_all_attributes
|
171
|
+
main_server.connected_clients.each_pair{|cc,cdb|
|
172
|
+
if cdb == client.name
|
173
|
+
begin
|
174
|
+
einfo("sending reload attribute to #{cc}")
|
175
|
+
cc.rpc("GtkAttributeStorage.instance.load_all")
|
176
|
+
rescue => err
|
177
|
+
ewarn("cannot send reload attributes #{err}")
|
178
|
+
end
|
179
|
+
end
|
180
|
+
}
|
181
|
+
end
|
182
|
+
|
183
|
+
def reload_client_events(goid)
|
184
|
+
einfo("changed client event: #{goid}")
|
185
|
+
client.events(goid,true)
|
186
|
+
main_server.connected_clients.each_pair{|cc,cdb|
|
187
|
+
if cdb == client.name
|
188
|
+
begin
|
189
|
+
einfo("sending reload event to #{cc}")
|
190
|
+
cc.rpc("EventCache.instance.reload_events(\"#{goid}\")")
|
191
|
+
rescue => err
|
192
|
+
ewarn("cannot send reload events #{err}")
|
193
|
+
end
|
194
|
+
end
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
198
|
+
def auth?(nick,password)
|
199
|
+
r=@users.auth?(nick,password)
|
200
|
+
edebug("auth?(#{nick}):#{r}")
|
201
|
+
r
|
202
|
+
end
|
203
|
+
def sendmail(nick,subject,body)
|
204
|
+
sendmail_to_nick(nick,subject,body)
|
205
|
+
end
|
206
|
+
def user_in_group?(user_id,group_id)
|
207
|
+
@users.user_in_group?(user_id,group_id)
|
208
|
+
end
|
209
|
+
|
210
|
+
def moditems_with_base(base)
|
211
|
+
@moditems.each_value{|drblist|
|
212
|
+
yield drblist if drblist && drblist.mod_type == "list" && drblist.base == base
|
213
|
+
}
|
214
|
+
end
|
215
|
+
|
216
|
+
def changed_ids_of_base(base,ids,nick=nil)
|
217
|
+
base_moditem=nil
|
218
|
+
moditems_with_base(base){|b|
|
219
|
+
base_moditem=b
|
220
|
+
}
|
221
|
+
unless base_moditem.nil?
|
222
|
+
base_moditem.rows_changed(ids,nick)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def lock_id_of_base(base,lid)
|
227
|
+
ids=if lid.class == Array then lid else [lid] end
|
228
|
+
moditems_with_base(base){|b| ids.each{|iid| b.lock_iter(iid)}}
|
229
|
+
end
|
230
|
+
|
231
|
+
def unlock_id_of_base(base,lid)
|
232
|
+
ids=if lid.class == Array then lid else [lid] end
|
233
|
+
moditems_with_base(base){|b| ids.each{|iid| b.unlock_iter(iid)}}
|
234
|
+
end
|
235
|
+
|
236
|
+
def each_moditem(modtype = "list")
|
237
|
+
@moditems.each_value{|m|
|
238
|
+
yield m if m.mod_type == modtype
|
239
|
+
}
|
240
|
+
end
|
241
|
+
|
242
|
+
def remove_dead_clients
|
243
|
+
cnt=0
|
244
|
+
@moditems.each_value{|m| cnt+=m.remove_dead_clients if m.mod_type == "list"}
|
245
|
+
cnt
|
246
|
+
end
|
247
|
+
|
248
|
+
def alive?
|
249
|
+
true
|
250
|
+
# server.alive?
|
251
|
+
end
|
252
|
+
|
253
|
+
# def method_missing(sym,*args)
|
254
|
+
# p "#{self} missing method: #{sym}(#{args})"
|
255
|
+
# end
|
256
|
+
|
257
|
+
def report_mail(subject, variables)
|
258
|
+
@main_server.report_mail(subject,variables)
|
259
|
+
end
|
260
|
+
|
261
|
+
def exit
|
262
|
+
@server.stop_service
|
263
|
+
super
|
264
|
+
end
|
265
|
+
|
266
|
+
def serving?
|
267
|
+
@state==SERVING
|
268
|
+
end
|
269
|
+
|
270
|
+
def to_s
|
271
|
+
"[ManqodDb #{name}(#{Process.pid})]"
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
data/lib/Eprint.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
#this file is part of manqod
|
2
|
+
#manqod is distributed under the CDDL licence
|
3
|
+
#the author of manqod is Dobai-Pataky Balint(dpblnt@gmail.com)
|
4
|
+
|
5
|
+
module Eprint
|
6
|
+
TERM_COLOUR={
|
7
|
+
Logger::Severity::DEBUG => 33,
|
8
|
+
Logger::Severity::INFO => 32,
|
9
|
+
Logger::Severity::WARN => 35,
|
10
|
+
Logger::Severity::ERROR => 31,
|
11
|
+
Logger::Severity::FATAL => 31,
|
12
|
+
Logger::Severity::UNKNOWN => 36
|
13
|
+
}
|
14
|
+
def eprint(subject,level=Logger::Severity::UNKNOWN)
|
15
|
+
begin
|
16
|
+
ManqodLogger.instance.log(level,"\e[1;37m#{self}\e[0m:\e[#{TERM_COLOUR[level]}m#{subject}\e[0m")
|
17
|
+
rescue => err
|
18
|
+
print("#{err}\n")
|
19
|
+
ManqodLogger.instance.set_level("ERROR")
|
20
|
+
retry
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def edebug(subject)
|
25
|
+
eprint(subject,Logger::Severity::DEBUG)
|
26
|
+
end
|
27
|
+
|
28
|
+
def einfo(subject)
|
29
|
+
eprint(subject,Logger::Severity::INFO)
|
30
|
+
end
|
31
|
+
|
32
|
+
def ewarn(subject)
|
33
|
+
eprint(subject,Logger::Severity::WARN)
|
34
|
+
end
|
35
|
+
|
36
|
+
def eerror(subject)
|
37
|
+
eprint(subject,Logger::Severity::ERROR)
|
38
|
+
end
|
39
|
+
def efatal(subject)
|
40
|
+
eprint(subject,Logger::Severity::FATAL)
|
41
|
+
end
|
42
|
+
|
43
|
+
def ecode(subject)
|
44
|
+
eprint(subject,Logger::Severity::UNKNOWN)
|
45
|
+
end
|
46
|
+
|
47
|
+
def report_mail(subject, variables)
|
48
|
+
return unless ManqodLogger.instance.report_address
|
49
|
+
fork{
|
50
|
+
begin
|
51
|
+
msg="From: manqod@#{Socket.gethostbyname(Socket.gethostname).first}\nTo: #{ManqodLogger.instance.report_address}\nSubject: #{subject}\n"
|
52
|
+
variables.each_pair{|k,v| msg="#{msg}\n#{k}: #{v}\n--------------------"}
|
53
|
+
|
54
|
+
Net::SMTP.start('localhost'){ |smtp|
|
55
|
+
smtp.send_message(msg, "manqod_server", ManqodLogger.instance.report_address)
|
56
|
+
einfo("report sent: #{subject} to {ManqodLogger.instance.report_address}")
|
57
|
+
}
|
58
|
+
rescue => err
|
59
|
+
eerror("can't send error report via SMTP")
|
60
|
+
end
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def eexception(ex,*args)
|
65
|
+
eerror("error: #{ex}\n#{ex.backtrace.join("\n")}")
|
66
|
+
report_mail(ex,{
|
67
|
+
'error'=>ex.inspect,
|
68
|
+
'backtrace'=>ex.backtrace.join("\n"),
|
69
|
+
'class' => self.class,
|
70
|
+
'self'=>self.inspect,
|
71
|
+
'arguments' => args.inspect
|
72
|
+
})
|
73
|
+
end
|
74
|
+
|
75
|
+
def eeval(command,context=self)
|
76
|
+
ret=nil
|
77
|
+
begin
|
78
|
+
if context and b=context.getBinding then
|
79
|
+
ret=eval(command, b)
|
80
|
+
else
|
81
|
+
ret=eval(command)
|
82
|
+
end
|
83
|
+
rescue SyntaxError, NameError => err
|
84
|
+
eexception(err,:command=>command,:context=>context)
|
85
|
+
end
|
86
|
+
ret
|
87
|
+
end
|
88
|
+
|
89
|
+
def getBinding
|
90
|
+
binding
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
data/lib/HeartBeat.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#this file is part of manqod
|
2
|
+
#manqod is distributed under the CDDL licence
|
3
|
+
#the author of manqod is Dobai-Pataky Balint(dpblnt@gmail.com)
|
4
|
+
|
5
|
+
module HeartBeat
|
6
|
+
def init_HeartBeat
|
7
|
+
@headerbeat_thread=Thread.new{
|
8
|
+
lalive_clients=-1
|
9
|
+
lalive_client_lists=-1
|
10
|
+
loop do
|
11
|
+
begin
|
12
|
+
sleep 10
|
13
|
+
to_remove=Array.new
|
14
|
+
alive_clients=0
|
15
|
+
@connected_clients.each_pair{|cc,db|
|
16
|
+
begin
|
17
|
+
cc.alive?
|
18
|
+
alive_clients+=1
|
19
|
+
rescue
|
20
|
+
to_remove.push(cc)
|
21
|
+
end
|
22
|
+
}
|
23
|
+
to_remove.each{|dead|
|
24
|
+
ewarn("removed dead client: #{dead.inspect}")
|
25
|
+
@connected_clients.delete(dead)
|
26
|
+
}
|
27
|
+
|
28
|
+
alive_client_lists=0
|
29
|
+
@dbs.each_value{|db|
|
30
|
+
next unless db.serving?
|
31
|
+
#keep the conenction to the cache alive
|
32
|
+
db.cache.set("alive",Time.new)
|
33
|
+
#check for alive client list subscriptions
|
34
|
+
alive_client_lists+=db.remove_dead_clients
|
35
|
+
}
|
36
|
+
einfo("#{alive_clients} clients #{alive_client_lists} subscriptions alive") unless alive_clients==lalive_clients && alive_client_lists==lalive_client_lists
|
37
|
+
|
38
|
+
lalive_clients=alive_clients
|
39
|
+
lalive_client_lists=alive_client_lists
|
40
|
+
rescue ECONNREFUSED => err
|
41
|
+
eerror("HeartBeat: #{err}")
|
42
|
+
rescue =>err
|
43
|
+
eerror("HeartBeat error: #{err}\n#{err.backtrace.join("\n")}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
}
|
47
|
+
einfo("HeartBeat started")
|
48
|
+
end
|
49
|
+
def stop_HeartBeat
|
50
|
+
@heartbeat_thread.kill
|
51
|
+
einfo("HeartBeat stopped")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
data/lib/ManqodLogger.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#this file is part of manqod
|
2
|
+
#manqod is distributed under the CDDL licence
|
3
|
+
#the author of manqod is Dobai-Pataky Balint(dpblnt@gmail.com)
|
4
|
+
|
5
|
+
class ManqodLogger < Logger::Application
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
LEVEL_MAP={
|
9
|
+
"DEBUG" => Logger::Severity::DEBUG,
|
10
|
+
"INFO" => Logger::Severity::INFO,
|
11
|
+
"WARN" => Logger::Severity::WARN,
|
12
|
+
"ERROR" => Logger::Severity::ERROR,
|
13
|
+
"FATAL" => Logger::Severity::FATAL,
|
14
|
+
"UNKNOWN" => Logger::Severity::UNKNOWN
|
15
|
+
}
|
16
|
+
|
17
|
+
@report_address=nil
|
18
|
+
attr_reader :report_address
|
19
|
+
|
20
|
+
def set_level(llevel)
|
21
|
+
self.level=LEVEL_MAP[llevel]
|
22
|
+
end
|
23
|
+
def set_report_address(ra)
|
24
|
+
@report_address=ra
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
data/lib/ManqodServer.rb
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
#this file is part of manqod
|
2
|
+
#manqod is distributed under the CDDL licence
|
3
|
+
#the author of manqod is Dobai-Pataky Balint(dpblnt@gmail.com)
|
4
|
+
|
5
|
+
class ManqodServer
|
6
|
+
include Eprint
|
7
|
+
include DRb
|
8
|
+
include DRbUndumped
|
9
|
+
include HeartBeat
|
10
|
+
include DBSetup
|
11
|
+
def initialize(opts)
|
12
|
+
@starting_up=true
|
13
|
+
@uri=opts[:bind]
|
14
|
+
@logdev=opts[:log]
|
15
|
+
@log_level=opts[:debug]
|
16
|
+
@report_address=opts[:report]
|
17
|
+
@path=opts[:path]
|
18
|
+
@connections_conf=File::expand_path(File.join(File.join(@path,"etc"),"connections.conf"))
|
19
|
+
@conns=Hash.new
|
20
|
+
@dbs=Hash.new
|
21
|
+
@connected_clients=Hash.new
|
22
|
+
end
|
23
|
+
attr_reader :dbs, :connected_clients, :uri
|
24
|
+
attr_reader :starting_up
|
25
|
+
|
26
|
+
def init
|
27
|
+
ManqodLogger.instance.set_log(@logdev) if @logdev
|
28
|
+
einfo("setting log level to #{@log_level}")
|
29
|
+
ManqodLogger.instance.set_level(@log_level) if @log_level
|
30
|
+
ManqodLogger.instance.set_report_address(@report_address) if @report_address
|
31
|
+
load_conns
|
32
|
+
begin
|
33
|
+
DRb.start_service(@uri,self)
|
34
|
+
rescue =>err
|
35
|
+
eerror("starting main server failed: #{err}")
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
@conns.sort{|a,b| a[1]["auto_load_order"] <=> b[1]["auto_load_order"]}.each{|conn|
|
39
|
+
load_conn(conn[0]) if conn[1]["auto_load"]
|
40
|
+
}
|
41
|
+
setup_clients
|
42
|
+
init_HeartBeat
|
43
|
+
@starting_up=false
|
44
|
+
eprint("serving")
|
45
|
+
DRb.thread.join
|
46
|
+
einfo("graceful shutdown")
|
47
|
+
end
|
48
|
+
|
49
|
+
def setup_clients
|
50
|
+
#wait for all clients to start up
|
51
|
+
begin
|
52
|
+
begin
|
53
|
+
found=false
|
54
|
+
@dbs.each_value{|drbdb|
|
55
|
+
unless drbdb.serving?
|
56
|
+
found = true
|
57
|
+
sleep 1
|
58
|
+
end
|
59
|
+
}
|
60
|
+
end while found
|
61
|
+
@dbs.each_pair{|conn_name,drbdb| drbdb.setup_client unless drbdb.client and drbdb.client.alive?}
|
62
|
+
rescue
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def conn(conn_name)
|
67
|
+
@conns[conn_name]
|
68
|
+
end
|
69
|
+
|
70
|
+
def conn_list
|
71
|
+
@conns.each_pair{|conn_name,conn|
|
72
|
+
yield conn_name,conn
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
def default_connection
|
77
|
+
dc=nil
|
78
|
+
@conns.each_pair{|cn,c| dc=c if c.has_key?("client_default") && c["client_default"]}
|
79
|
+
dc
|
80
|
+
end
|
81
|
+
|
82
|
+
def reload_conn(conn_name)
|
83
|
+
if @conns.has_key?(conn_name)
|
84
|
+
free_conn(conn_name) if @dbs.has_key?(conn_name)
|
85
|
+
load_conn(conn_name)
|
86
|
+
setup_clients
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def load_conn(conn_name)
|
91
|
+
if @conns.has_key?(conn_name)
|
92
|
+
begin
|
93
|
+
@conns[conn_name]["key_name"]=conn_name
|
94
|
+
@conns[conn_name]['pid']=fork{
|
95
|
+
th=DrbDb.new(@conns[conn_name],@uri)
|
96
|
+
th.init
|
97
|
+
}
|
98
|
+
Process.detach(@conns[conn_name]['pid'])
|
99
|
+
edebug("forked \"#{conn_name}\" [#{@conns[conn_name]['uri']}](#{@conns[conn_name]['pid']})")
|
100
|
+
|
101
|
+
begin
|
102
|
+
sleep 1
|
103
|
+
@dbs[conn_name]=DRb::DRbObject.new_with_uri(@conns[conn_name]['uri'])
|
104
|
+
# @dbs[conn_name].alive?
|
105
|
+
@dbs[conn_name].state
|
106
|
+
@dbs[conn_name].setup_client
|
107
|
+
rescue => err
|
108
|
+
#check if pid is alive
|
109
|
+
begin
|
110
|
+
Process::kill(0,@conns[conn_name]['pid'])
|
111
|
+
rescue Errno::ESRCH
|
112
|
+
raise("Process with pid #{@conns[conn_name]['pid']} is dead")
|
113
|
+
end
|
114
|
+
ewarn("waiting for startup of #{conn_name} (#{err})")
|
115
|
+
retry
|
116
|
+
end while @dbs[conn_name].state != DrbDb::SERVING
|
117
|
+
rescue =>err
|
118
|
+
eerror("error starting connection:#{conn_name} #{err}, retrying")
|
119
|
+
sleep 1
|
120
|
+
retry
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def free_conn(conn_name)
|
126
|
+
if @dbs.has_key?(conn_name)
|
127
|
+
@dbs[conn_name].exit
|
128
|
+
@dbs.delete(conn_name)
|
129
|
+
einfo("#{conn_name} freed.")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def stop
|
134
|
+
@dbs.each_key{|dbn|
|
135
|
+
begin
|
136
|
+
free_conn(dbn)
|
137
|
+
rescue =>err
|
138
|
+
eerror("cannot stop #{dbn}:#{err}")
|
139
|
+
end
|
140
|
+
}
|
141
|
+
current_server.stop_service
|
142
|
+
einfo("server halted")
|
143
|
+
exit
|
144
|
+
end
|
145
|
+
|
146
|
+
def register_client(client,db)
|
147
|
+
@connected_clients[client]=db unless @connected_clients.has_key?(client)
|
148
|
+
einfo("#{client} registered to [#{db}]")
|
149
|
+
end
|
150
|
+
def unregister_client(client)
|
151
|
+
@connected_clients.delete(client)
|
152
|
+
einfo("#{client} unregistered")
|
153
|
+
end
|
154
|
+
|
155
|
+
def alive?
|
156
|
+
true
|
157
|
+
end
|
158
|
+
|
159
|
+
def to_s
|
160
|
+
"ManqodServer"
|
161
|
+
end
|
162
|
+
|
163
|
+
# def method_missing(sym,*args)
|
164
|
+
# p "#{self} missing method: #{sym}(#{args})"
|
165
|
+
# end
|
166
|
+
end
|
167
|
+
|