manqod-server 1.269.0 → 1.280.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/manqod-server +3 -9
- data/doc/manqod.sql +11 -67
- data/doc/manqod_structure.sql +21 -25
- data/lib/DrbDB.rb +57 -17
- data/lib/DrbDB/DrbListModel.rb +42 -24
- data/lib/DrbDB/DrbRelationBuilder.rb +97 -0
- data/lib/DrbDB/Messaging.rb +1 -1
- data/lib/HeartBeat.rb +18 -11
- data/lib/ManqodServer.rb +16 -16
- metadata +4 -3
data/lib/DrbDB.rb
CHANGED
@@ -25,7 +25,7 @@ class DrbDb
|
|
25
25
|
# @relations=Hash.new
|
26
26
|
# @server=DRb::DRbServer.new(@connection['uri'],self)
|
27
27
|
end
|
28
|
-
attr_reader :uri, :moditems, :admin, :client, :cache, :connection, :images, :state
|
28
|
+
attr_reader :uri, :moditems, :admin, :client, :cache, :connection, :images, :state, :relation_builder
|
29
29
|
attr_accessor :server, :main_server
|
30
30
|
|
31
31
|
def init
|
@@ -61,6 +61,8 @@ class DrbDb
|
|
61
61
|
@moditems[moditem["id"].to_i].update(self)
|
62
62
|
when "form"
|
63
63
|
@moditems[moditem["id"].to_i]=DrbForm.new(self,moditem["id"].to_i).create_skeleton unless @moditems.has_key?(moditem["id"])
|
64
|
+
when "relation_builder"
|
65
|
+
@relation_builder=@moditems[moditem["id"].to_i]=DrbRelationBuilder.new(self,moditem["id"].to_i) unless @moditems.has_key?(moditem["id"])
|
64
66
|
else
|
65
67
|
ewarn("not caching #{moditem['display']}[#{moditem['modname']}]")
|
66
68
|
end
|
@@ -76,7 +78,7 @@ class DrbDb
|
|
76
78
|
start_cron
|
77
79
|
@state=SERVING
|
78
80
|
rescue => err
|
79
|
-
|
81
|
+
eexception(err)
|
80
82
|
retry
|
81
83
|
end
|
82
84
|
|
@@ -90,10 +92,22 @@ class DrbDb
|
|
90
92
|
begin
|
91
93
|
@client=DRb::DRbObject.new(nil,@connection['client_uri'])
|
92
94
|
einfo("client is alive?(#{@client}): #{@client.alive?}")
|
95
|
+
|
96
|
+
=begin
|
97
|
+
@moditems.each_value{|mi|
|
98
|
+
ecode(mi.class.name)
|
99
|
+
mi.update if mi.class == DrbRelationBuilder
|
100
|
+
}
|
101
|
+
=end
|
93
102
|
rescue
|
94
103
|
@client=nil
|
95
104
|
einfo("no client.")
|
96
105
|
end
|
106
|
+
begin
|
107
|
+
@relation_builder.update if @relation_builder && @client
|
108
|
+
rescue => err
|
109
|
+
eexception(err)
|
110
|
+
end
|
97
111
|
end
|
98
112
|
end
|
99
113
|
def name
|
@@ -141,7 +155,7 @@ class DrbDb
|
|
141
155
|
edebug("#{new_model} created")
|
142
156
|
new_model.update(self)
|
143
157
|
unless @moditems[moditem_id.to_i].nil?
|
144
|
-
@moditems[moditem_id.to_i].clients.
|
158
|
+
@moditems[moditem_id.to_i].clients.each_pair{|client_id,client| new_model.subscribe(client_id,client)}
|
145
159
|
edebug("#{@moditems[moditem_id.to_i]} abandoned")
|
146
160
|
end
|
147
161
|
@moditems[moditem_id.to_i]=new_model
|
@@ -158,41 +172,63 @@ class DrbDb
|
|
158
172
|
end
|
159
173
|
|
160
174
|
def reload_client_images
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
175
|
+
dead=Array.new
|
176
|
+
main_server.connected_clients.each_pair{|client_id,cdb|
|
177
|
+
if cdb[:db] == client.name
|
178
|
+
begin
|
179
|
+
einfo("sending reload images to #{client_id}")
|
180
|
+
sdb[:object].rpc("DrbImages.instance.load_images")
|
181
|
+
rescue => err
|
182
|
+
ewarn("cannot send reload images to #{client_id}")
|
183
|
+
dead.push(client_id)
|
184
|
+
end
|
165
185
|
end
|
166
186
|
}
|
187
|
+
dead.each{|client_id|
|
188
|
+
ewarn("killing dead client: #{client_id}")
|
189
|
+
remove_client(client_id)
|
190
|
+
}
|
167
191
|
end
|
168
192
|
|
169
193
|
def reload_client_attributes
|
170
194
|
client.load_all_attributes
|
171
|
-
|
172
|
-
|
195
|
+
dead=Array.new
|
196
|
+
main_server.connected_clients.each_pair{|client_id,cdb|
|
197
|
+
if cdb[:db] == client.name
|
173
198
|
begin
|
174
|
-
einfo("sending reload attribute to #{
|
175
|
-
|
199
|
+
einfo("sending reload attribute to #{client_id}")
|
200
|
+
cdb[:object].rpc("GtkAttributeStorage.instance.load_all")
|
176
201
|
rescue => err
|
177
|
-
ewarn("cannot send reload attributes #{
|
202
|
+
ewarn("cannot send reload attributes to #{client_id}")
|
203
|
+
dead.push(client_id)
|
178
204
|
end
|
179
205
|
end
|
180
206
|
}
|
207
|
+
dead.each{|client_id|
|
208
|
+
ewarn("killing dead client: #{client_id}")
|
209
|
+
remove_client(client_id)
|
210
|
+
}
|
181
211
|
end
|
182
212
|
|
183
213
|
def reload_client_events(goid)
|
184
214
|
einfo("changed client event: #{goid}")
|
185
215
|
client.events(goid,true)
|
186
|
-
|
187
|
-
|
216
|
+
dead=Array.new
|
217
|
+
main_server.connected_clients.each_pair{|client_id,cdb|
|
218
|
+
if cdb[:db] == client.name
|
188
219
|
begin
|
189
|
-
einfo("sending reload event to #{
|
190
|
-
|
220
|
+
einfo("sending reload event to #{client_id}")
|
221
|
+
cdb[:object].rpc("EventCache.instance.reload_events(\"#{goid}\")")
|
191
222
|
rescue => err
|
192
|
-
ewarn("cannot send reload events #{
|
223
|
+
ewarn("cannot send reload events to #{client_id}")
|
224
|
+
dead.push(client_id)
|
193
225
|
end
|
194
226
|
end
|
195
227
|
}
|
228
|
+
dead.each{|client_id|
|
229
|
+
ewarn("killing dead client: #{client_id}")
|
230
|
+
remove_client(client_id)
|
231
|
+
}
|
196
232
|
end
|
197
233
|
|
198
234
|
def auth?(nick,password)
|
@@ -248,6 +284,10 @@ class DrbDb
|
|
248
284
|
cnt
|
249
285
|
end
|
250
286
|
|
287
|
+
def remove_client(client_id)
|
288
|
+
@moditems.each_value{|m| m.clients.delete(client_id) if m.mod_type == "list"}
|
289
|
+
end
|
290
|
+
|
251
291
|
def alive?
|
252
292
|
true
|
253
293
|
# server.alive?
|
data/lib/DrbDB/DrbListModel.rb
CHANGED
@@ -17,7 +17,7 @@ class DrbListModel
|
|
17
17
|
@fetch_filter_value=nil
|
18
18
|
@fetch_filter_negate=false
|
19
19
|
@archive_key=nil
|
20
|
-
@clients=
|
20
|
+
@clients=Hash.new
|
21
21
|
@base=nil
|
22
22
|
@last_seq=Hash.new
|
23
23
|
@buttons=Array.new
|
@@ -205,7 +205,10 @@ class DrbListModel
|
|
205
205
|
@column_of_fetch_filter=if @fetch_filter_key then headers[@fetch_filter_key]["model_col"] else nil end
|
206
206
|
@column_of_archive=if @archive_key then headers[@archive_key]["model_col"] else nil end
|
207
207
|
hdebug="#{hdebug}\nheadertypes: #{@headertypes.inspect}\nheaders:\n"
|
208
|
-
|
208
|
+
|
209
|
+
@background_legend=Hash.new
|
210
|
+
@foreground_legend=Hash.new
|
211
|
+
|
209
212
|
@headers.each_value{|val| hdebug="#{hdebug} #{val['data']} #{val['model_col']}\n"}
|
210
213
|
# print "#{self} #{hdebug}\n"
|
211
214
|
@column_of_tree=nil
|
@@ -343,6 +346,18 @@ class DrbListModel
|
|
343
346
|
else
|
344
347
|
row[header['data']]
|
345
348
|
end
|
349
|
+
#prepare background color
|
350
|
+
if @column_of_background == header['model_col'] && iter[@column_of_background].class == String
|
351
|
+
cl=iter[@column_of_background].split(":")
|
352
|
+
iter[@column_of_background]=cl[0]
|
353
|
+
@background_legend[cl[0]]=cl[1]
|
354
|
+
end
|
355
|
+
#prepare foreground color
|
356
|
+
if @column_of_foreground == header['model_col'] && iter[@column_of_foreground].class == String
|
357
|
+
cl=iter[@column_of_foreground].split(":")
|
358
|
+
iter[@column_of_foreground]=cl[0]
|
359
|
+
@foreground_legend[cl[0]]=cl[1]
|
360
|
+
end
|
346
361
|
#history
|
347
362
|
unless row_backup.nil?
|
348
363
|
if header.has_key?("id") && row_backup[header['model_col']] != iter[header['model_col']]
|
@@ -360,6 +375,10 @@ class DrbListModel
|
|
360
375
|
@rowcount+=1 unless ids
|
361
376
|
}
|
362
377
|
|
378
|
+
#store fore and background legends
|
379
|
+
cache.set("#{@my_id}foreground",@foreground_legend)
|
380
|
+
cache.set("#{@my_id}background",@background_legend)
|
381
|
+
|
363
382
|
if ids and qres.size == 0
|
364
383
|
edebug("removed #{ids.inspect}")
|
365
384
|
#we were called to load_data of a non existing id, which means it was deleted
|
@@ -582,41 +601,41 @@ class DrbListModel
|
|
582
601
|
end
|
583
602
|
=end
|
584
603
|
|
585
|
-
def subscribe(client)
|
586
|
-
if @clients.
|
604
|
+
def subscribe(client_id,client)
|
605
|
+
if @clients.has_key?(client_id)
|
587
606
|
false
|
588
|
-
|
589
|
-
|
590
|
-
@clients
|
607
|
+
else
|
608
|
+
edebug("subscribing: #{client_id}")
|
609
|
+
@clients[client_id]=client
|
591
610
|
true
|
592
611
|
end
|
593
612
|
end
|
594
613
|
|
595
|
-
def unsubscribe(
|
596
|
-
|
597
|
-
@clients.delete(
|
614
|
+
def unsubscribe(client_id)
|
615
|
+
edebug("unsubscribing: #{client_id}")
|
616
|
+
@clients.delete(client_id)
|
598
617
|
end
|
599
618
|
|
600
619
|
def notify_clients(*args)
|
601
620
|
to_remove=Array.new
|
602
621
|
th=Array.new
|
603
622
|
edebug("notifying #{@clients.size} clients for #{args.inspect}") unless @drbdb.main_server.starting_up || @clients.size==0
|
604
|
-
@clients.
|
623
|
+
@clients.each_pair{|client_id,client|
|
605
624
|
th << Thread.new{
|
606
625
|
begin
|
607
626
|
if client.alive?
|
608
627
|
client.update(self.class.name,*args)
|
609
628
|
end
|
610
629
|
rescue =>err
|
611
|
-
|
612
|
-
to_remove.push(
|
630
|
+
eexception(err)
|
631
|
+
to_remove.push(client_id)
|
613
632
|
end
|
614
633
|
}
|
615
634
|
}
|
616
635
|
th.each{|t| t.join}
|
617
636
|
to_remove.each{|dead|
|
618
637
|
@clients.delete(dead)
|
619
|
-
edebug("dead client deleted")
|
638
|
+
edebug("dead client deleted: #{dead}")
|
620
639
|
}
|
621
640
|
end
|
622
641
|
|
@@ -649,19 +668,18 @@ class DrbListModel
|
|
649
668
|
|
650
669
|
def remove_dead_clients
|
651
670
|
alive_clients=0
|
652
|
-
|
653
|
-
clients.each{|client|
|
671
|
+
clients.delete_if{|client_id,client|
|
654
672
|
begin
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
673
|
+
Timeout.timeout(3){
|
674
|
+
client.alive?
|
675
|
+
alive_clients+=1
|
676
|
+
false
|
677
|
+
}
|
678
|
+
rescue
|
679
|
+
ewarn("removing dead subscription: #{client_id.inspect}")
|
680
|
+
true
|
659
681
|
end
|
660
682
|
}
|
661
|
-
to_remove.each{|dead|
|
662
|
-
ewarn("removed dead subscription: #{dead.inspect}")
|
663
|
-
clients.delete(dead)
|
664
|
-
}
|
665
683
|
alive_clients
|
666
684
|
end
|
667
685
|
|
@@ -0,0 +1,97 @@
|
|
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 DrbRelationBuilder
|
6
|
+
include Eprint
|
7
|
+
include DRbUndumped
|
8
|
+
|
9
|
+
def initialize(drbdb,my_id)
|
10
|
+
@my_id=my_id.to_i
|
11
|
+
@drbdb=drbdb
|
12
|
+
@title="Relation Builder"
|
13
|
+
@relations=Hash.new
|
14
|
+
@tables=Hash.new
|
15
|
+
|
16
|
+
end
|
17
|
+
attr_reader :moditem
|
18
|
+
|
19
|
+
def update
|
20
|
+
@relations.clear
|
21
|
+
@tables.clear
|
22
|
+
@drbdb.rows("select * from tables").each{|row|
|
23
|
+
@tables[row["name"]]={
|
24
|
+
"id" => row["id"],
|
25
|
+
"name" => row["name"],
|
26
|
+
"rbx" => row["rbx"].to_f,
|
27
|
+
"rby" => row["rby"].to_f
|
28
|
+
}
|
29
|
+
#indexes
|
30
|
+
begin
|
31
|
+
@tables[row["name"]]["indexes"]=Array.new
|
32
|
+
@drbdb.client.rows("show indexes from #{row['name']}").each{|index|
|
33
|
+
@tables[row["name"]]["indexes"].push({
|
34
|
+
"name"=>index["Key_name"],
|
35
|
+
"unique"=>index["Non_unique"]=="0",
|
36
|
+
"field"=>index["Column_name"]
|
37
|
+
}
|
38
|
+
)
|
39
|
+
}
|
40
|
+
rescue => err
|
41
|
+
eerror(err)
|
42
|
+
end
|
43
|
+
|
44
|
+
#is view?
|
45
|
+
is_view=false
|
46
|
+
begin
|
47
|
+
@drbdb.client.fields("show create table `#{row['name']}`").each{|f| is_view=true if f["name"].include?("View")}
|
48
|
+
@tables[row["name"]]["view"]=is_view
|
49
|
+
rescue => err
|
50
|
+
eerror(err)
|
51
|
+
end
|
52
|
+
|
53
|
+
#fields
|
54
|
+
@tables[row["name"]]["fields"]=Hash.new
|
55
|
+
begin
|
56
|
+
@drbdb.client.rows("show fields from #{row['name']}").each{|field|
|
57
|
+
fi=field.rehash
|
58
|
+
if f=field["Type"].index("(")
|
59
|
+
fi["Size"]=field["Type"][f+1 .. field["Type"].index(")") -1]
|
60
|
+
fi["Type"]=field["Type"][0 .. f-1]
|
61
|
+
end
|
62
|
+
@tables[row["name"]]["fields"][field["Field"]]=fi
|
63
|
+
}
|
64
|
+
rescue => err
|
65
|
+
eerror(err)
|
66
|
+
end
|
67
|
+
|
68
|
+
}
|
69
|
+
@drbdb.rows("select * from relations").each{|row|
|
70
|
+
@relations[row["id"]]={
|
71
|
+
"id" => row["id"],
|
72
|
+
"src_table" => row["src_table"],
|
73
|
+
"src_field" => row["src_field"],
|
74
|
+
"dst_table" => row["dst_table"],
|
75
|
+
"dst_field" => row["dst_field"],
|
76
|
+
"rel_name" => row['rel_name'],
|
77
|
+
"rel_type" => row["rel_type"],
|
78
|
+
"rbx" => row["rbx"].to_f,
|
79
|
+
"rby" => row["rby"].to_f,
|
80
|
+
"rel_custom" => row['rel_custom']
|
81
|
+
}
|
82
|
+
}
|
83
|
+
@drbdb.cache.set("tables",@tables)
|
84
|
+
einfo("#{@tables.size} tables")
|
85
|
+
@drbdb.cache.set("relations",@relations)
|
86
|
+
einfo("#{@relations.size} relations")
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
def mod_type
|
91
|
+
"relation_builder"
|
92
|
+
end
|
93
|
+
|
94
|
+
def to_s
|
95
|
+
"#{@drbdb}.RelationBuilder"
|
96
|
+
end
|
97
|
+
end
|
data/lib/DrbDB/Messaging.rb
CHANGED
@@ -7,7 +7,7 @@ module Messaging
|
|
7
7
|
nick=[nick] unless nick.class == Array
|
8
8
|
Thread.new{
|
9
9
|
nick.each{|n|
|
10
|
-
admin.query("insert into messages (sender,recipient,subject,body,state,`date`) values('#{sender || "system"}','#{n}','#{subject}','#{body}','n',now())")
|
10
|
+
admin.query("insert into messages (sender,recipient,subject,body,state,`date`) values('#{sender || "system"}','#{n}','#{admin.escape_string(subject)}','#{admin.escape_string(body)}','n',now())")
|
11
11
|
send_check_messages(n)
|
12
12
|
}
|
13
13
|
}
|
data/lib/HeartBeat.rb
CHANGED
@@ -12,18 +12,25 @@ module HeartBeat
|
|
12
12
|
sleep 10
|
13
13
|
to_remove=Array.new
|
14
14
|
alive_clients=0
|
15
|
-
@connected_clients.
|
15
|
+
@connected_clients.delete_if{|client_id,cdb|
|
16
16
|
begin
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
Timeout.timeout(3){
|
18
|
+
#ecode("#{cc}.alive?:#{cc.alive?}")
|
19
|
+
cdb[:object].alive?
|
20
|
+
alive_clients+=1
|
21
|
+
false
|
22
|
+
}
|
23
|
+
rescue Timeout::Error
|
24
|
+
ewarn("client timed out, removing a dead client #{client_id}")
|
25
|
+
true
|
26
|
+
rescue => err
|
27
|
+
ewarn("removing a dead client #{client_id}")
|
28
|
+
@dbs.each_value{|db|
|
29
|
+
db.remove_client(client_id) unless db.serving?
|
30
|
+
}
|
31
|
+
true
|
21
32
|
end
|
22
33
|
}
|
23
|
-
to_remove.each{|dead|
|
24
|
-
ewarn("removed dead client: #{dead.inspect}")
|
25
|
-
@connected_clients.delete(dead)
|
26
|
-
}
|
27
34
|
|
28
35
|
alive_client_lists=0
|
29
36
|
@dbs.each_value{|db|
|
@@ -33,14 +40,14 @@ module HeartBeat
|
|
33
40
|
#check for alive client list subscriptions
|
34
41
|
alive_client_lists+=db.remove_dead_clients
|
35
42
|
}
|
36
|
-
einfo("#{alive_clients} clients
|
43
|
+
einfo("#{alive_clients} clients, #{alive_client_lists} subscriptions") unless alive_clients==lalive_clients && alive_client_lists==lalive_client_lists
|
37
44
|
|
38
45
|
lalive_clients=alive_clients
|
39
46
|
lalive_client_lists=alive_client_lists
|
40
47
|
rescue ECONNREFUSED => err
|
41
48
|
eerror("HeartBeat: #{err}")
|
42
49
|
rescue =>err
|
43
|
-
|
50
|
+
eexception(err)
|
44
51
|
end
|
45
52
|
end
|
46
53
|
}
|
data/lib/ManqodServer.rb
CHANGED
@@ -49,16 +49,16 @@ class ManqodServer
|
|
49
49
|
def setup_clients
|
50
50
|
#wait for all clients to start up
|
51
51
|
begin
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
62
|
rescue
|
63
63
|
end
|
64
64
|
end
|
@@ -143,13 +143,13 @@ class ManqodServer
|
|
143
143
|
exit
|
144
144
|
end
|
145
145
|
|
146
|
-
def register_client(
|
147
|
-
@connected_clients[
|
148
|
-
einfo("#{
|
146
|
+
def register_client(client_id,client_object,client_db)
|
147
|
+
@connected_clients[client_id.clone]={:object => client_object, :db => client_db} unless @connected_clients.has_key?(client_id)
|
148
|
+
einfo("#{client_id} registered to [#{client_db}]")
|
149
149
|
end
|
150
|
-
def unregister_client(
|
151
|
-
@connected_clients.delete(
|
152
|
-
einfo("#{
|
150
|
+
def unregister_client(client_id)
|
151
|
+
@connected_clients.delete(client_id)
|
152
|
+
einfo("#{client_id} unregistered")
|
153
153
|
end
|
154
154
|
|
155
155
|
def alive?
|