knjappserver 0.0.15 → 0.0.16
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -2
- data/Gemfile.lock +24 -10
- data/README.rdoc +298 -1
- data/VERSION +1 -1
- data/bin/check_running.rb +2 -2
- data/knjappserver.gemspec +23 -5
- data/lib/files/database_schema.rb +124 -111
- data/lib/include/class_customio.rb +19 -5
- data/lib/include/class_erbhandler.rb +5 -22
- data/lib/include/class_httpresp.rb +66 -28
- data/lib/include/class_httpserver.rb +27 -14
- data/lib/include/class_httpsession.rb +161 -212
- data/lib/include/class_httpsession_contentgroup.rb +144 -0
- data/lib/include/class_httpsession_knjengine.rb +33 -68
- data/lib/include/class_httpsession_mongrel.rb +1 -1
- data/lib/include/class_httpsession_webrick.rb +1 -1
- data/lib/include/class_knjappserver.rb +105 -130
- data/lib/include/class_knjappserver_cleaner.rb +20 -13
- data/lib/include/class_knjappserver_cmdline.rb +44 -0
- data/lib/include/class_knjappserver_errors.rb +4 -1
- data/lib/include/class_knjappserver_logging.rb +48 -8
- data/lib/include/class_knjappserver_mailing.rb +36 -14
- data/lib/include/class_knjappserver_sessions.rb +78 -0
- data/lib/include/class_knjappserver_threadding.rb +18 -45
- data/lib/include/class_knjappserver_threadding_timeout.rb +78 -0
- data/lib/include/class_knjappserver_translations.rb +30 -0
- data/lib/include/class_knjappserver_web.rb +55 -3
- data/lib/include/class_log.rb +31 -3
- data/lib/include/class_log_access.rb +0 -15
- data/lib/include/class_log_data.rb +0 -15
- data/lib/include/class_log_data_link.rb +1 -14
- data/lib/include/class_log_data_value.rb +5 -17
- data/lib/include/class_session.rb +6 -18
- data/lib/include/magic_methods.rb +12 -14
- data/lib/pages/benchmark.rhtml +0 -0
- data/lib/pages/benchmark_print.rhtml +14 -0
- data/lib/pages/benchmark_simple.rhtml +3 -0
- data/lib/pages/benchmark_threadded_content.rhtml +21 -0
- data/lib/pages/spec.rhtml +26 -0
- data/lib/pages/spec_test_multiple_clients.rhtml +3 -0
- data/lib/pages/spec_threadded_content.rhtml +38 -0
- data/lib/scripts/benchmark.rb +65 -0
- data/spec/knjappserver_spec.rb +87 -43
- metadata +54 -20
@@ -13,7 +13,8 @@ class Knjappserver
|
|
13
13
|
|
14
14
|
if @config.has_key?(:restart_when_used_memory) and !@should_restart
|
15
15
|
mbs_used = (Knj::Php.memory_get_usage / 1024) / 1024
|
16
|
-
|
16
|
+
STDOUT.print "Restart when over #{@config[:restart_when_used_memory]}mb\n" if @config[:debug]
|
17
|
+
STDOUT.print "Used: #{mbs_used}mb\n" if @config[:debug]
|
17
18
|
|
18
19
|
if mbs_used.to_i >= @config[:restart_when_used_memory].to_i
|
19
20
|
STDOUT.print "Memory is over #{@config[:restart_when_used_memory]} - restarting.\n"
|
@@ -25,7 +26,7 @@ class Knjappserver
|
|
25
26
|
begin
|
26
27
|
@should_restart_runnning = true
|
27
28
|
|
28
|
-
#When we begin to restart it should go as fast as possible - so start by flushing out any emails waiting...
|
29
|
+
#When we begin to restart it should go as fast as possible - so start by flushing out any emails waiting so it goes faster the last time...
|
29
30
|
STDOUT.print "Flushing mails.\n"
|
30
31
|
self.mail_flush
|
31
32
|
|
@@ -89,19 +90,25 @@ class Knjappserver
|
|
89
90
|
STDOUT.print "Cleaning sessions on appserver.\n" if @config[:debug]
|
90
91
|
|
91
92
|
self.paused_exec do
|
93
|
+
session_not_ids = []
|
92
94
|
time_check = Time.now.to_i - 300
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
session_data[:dbobj].flush
|
97
|
-
@ob.unset(session_data[:dbobj])
|
98
|
-
session_data[:hash].clear
|
99
|
-
ip_sessions.delete(session_hash)
|
100
|
-
session_data.clear
|
101
|
-
end
|
102
|
-
end
|
95
|
+
newsessions = {}
|
96
|
+
@sessions.each do |session_hash, session_data|
|
97
|
+
session_data[:dbobj].flush
|
103
98
|
|
104
|
-
|
99
|
+
if session_data[:time_lastused].to_i > time_check
|
100
|
+
newsessions[session_hash] = session_data
|
101
|
+
session_not_ids << session_data[:dbobj].id
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
@sessions = newsessions
|
106
|
+
|
107
|
+
STDOUT.print "Delete sessions...\n" if @config[:debug]
|
108
|
+
@ob.list(:Session, {"id_not" => session_not_ids, "date_lastused_below" => (Time.now - 5356800)}) do |session|
|
109
|
+
@ob.delete(session)
|
110
|
+
@sessions.delete(session[:idhash])
|
111
|
+
STDOUT.print "Deleted session: #{session.id}\n" if @config[:debug]
|
105
112
|
end
|
106
113
|
end
|
107
114
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class Knjappserver
|
2
|
+
def initialize_cmdline
|
3
|
+
@cmds = {}
|
4
|
+
|
5
|
+
Knj::Thread.new do
|
6
|
+
line = $stdin.gets
|
7
|
+
|
8
|
+
called = 0
|
9
|
+
@cmds.each do |key, connects|
|
10
|
+
data = {}
|
11
|
+
|
12
|
+
if key.is_a?(Regexp)
|
13
|
+
if line.match(key)
|
14
|
+
connects.each do |conn|
|
15
|
+
called += 1
|
16
|
+
conn[:block].call(data)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
else
|
20
|
+
raise "Unknown class for 'cmd_connect': '#{key.class.name}'."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
if called == 0
|
25
|
+
print "Unknown command: '#{line.strip}'.\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
self.cmd_connect(/^\s*restart\s*$/i) do |data|
|
30
|
+
print "Restart will begin shortly.\n"
|
31
|
+
self.should_restart = true
|
32
|
+
end
|
33
|
+
|
34
|
+
self.cmd_connect(/^\s*stop\s*$/i) do |data|
|
35
|
+
self.stop
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
#Connects a proc to a specific command in the command-line (key should be a regex).
|
40
|
+
def cmd_connect(cmd, &block)
|
41
|
+
@cmds[cmd] = [] if !@cmds.key?(cmd)
|
42
|
+
@cmds[cmd] << {:block => block}
|
43
|
+
end
|
44
|
+
end
|
@@ -18,6 +18,7 @@ class Knjappserver
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
#Send error-emails based on error-emails-cache (cached so the same error isnt send out every time it occurrs to prevent spamming).
|
21
22
|
def flush_error_emails
|
22
23
|
@error_emails_pending_mutex.synchronize do
|
23
24
|
send_time_older_than = Time.new.to_i - @error_emails_time
|
@@ -65,6 +66,7 @@ class Knjappserver
|
|
65
66
|
end
|
66
67
|
end
|
67
68
|
|
69
|
+
#Handels a given error. Sends to the admin-emails.
|
68
70
|
def handle_error(e, args = {})
|
69
71
|
@error_emails_pending_mutex.synchronize do
|
70
72
|
if !Thread.current[:knjappserver] or !Thread.current[:knjappserver][:httpsession]
|
@@ -82,7 +84,7 @@ class Knjappserver
|
|
82
84
|
@error_emails_pending[backtrace_hash] = {
|
83
85
|
:first_time => Time.new,
|
84
86
|
:messages => [],
|
85
|
-
:subject => sprintf("Error @ %s", @config[:title]) + " (#{e.message})"
|
87
|
+
:subject => sprintf("Error @ %s", @config[:title]) + " (#{Knj::Strings.shorten(e.message, 100)})"
|
86
88
|
}
|
87
89
|
end
|
88
90
|
|
@@ -107,6 +109,7 @@ class Knjappserver
|
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
112
|
+
#Takes a proc and executes it. On error it alerts the error-message with javascript to the server, sends a javascript back and exits.
|
110
113
|
def on_error_go_back(&block)
|
111
114
|
begin
|
112
115
|
block.call
|
@@ -12,6 +12,7 @@ class Knjappserver
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
#Writes all queued access-logs to the database.
|
15
16
|
def flush_access_log
|
16
17
|
@logs_mutex.synchronize do
|
17
18
|
ins_arr = @logs_access_pending
|
@@ -155,8 +156,12 @@ class Knjappserver
|
|
155
156
|
end
|
156
157
|
|
157
158
|
def log_data_hash(keys_id, values_id)
|
158
|
-
|
159
|
-
|
159
|
+
begin
|
160
|
+
keys_data_obj = @ob.get(:Log_data, keys_id)
|
161
|
+
values_data_obj = @ob.get(:Log_data, values_id)
|
162
|
+
rescue Knj::Errors::NotFound
|
163
|
+
return {}
|
164
|
+
end
|
160
165
|
|
161
166
|
sql = "
|
162
167
|
SELECT
|
@@ -181,20 +186,20 @@ class Knjappserver
|
|
181
186
|
"
|
182
187
|
|
183
188
|
hash = {}
|
184
|
-
|
185
|
-
while d_hash = q_hash.fetch
|
189
|
+
db.q(sql) do |d_hash|
|
186
190
|
hash[d_hash[:key].to_sym] = d_hash[:value]
|
187
191
|
end
|
188
192
|
|
189
193
|
return hash
|
190
194
|
end
|
191
195
|
|
192
|
-
|
196
|
+
#Writes a custom log to the database.
|
197
|
+
def log(msg, objs, args = {})
|
193
198
|
@logs_mutex.synchronize do
|
194
199
|
objs = [objs] if !objs.is_a?(Array)
|
195
200
|
log_value_id = @ob.static(:Log_data_value, :force_id, msg)
|
196
201
|
ins_data = {
|
197
|
-
:date_saved => Time.
|
202
|
+
:date_saved => Time.now,
|
198
203
|
:text_value_id => log_value_id
|
199
204
|
}
|
200
205
|
|
@@ -210,6 +215,28 @@ class Knjappserver
|
|
210
215
|
ins_data[:post_values_data_id] = post_hash[:values_data_id]
|
211
216
|
end
|
212
217
|
|
218
|
+
cookie_hash = log_hash_ins(_cookie) if _cookie
|
219
|
+
if cookie_hash
|
220
|
+
ins_data[:post_keys_data_id] = cookie_hash[:keys_data_id]
|
221
|
+
ins_data[:post_values_data_id] = cookie_hash[:values_data_id]
|
222
|
+
end
|
223
|
+
|
224
|
+
meta_hash = log_hash_ins(_meta) if _meta
|
225
|
+
if cookie_hash
|
226
|
+
ins_data[:meta_keys_data_id] = meta_hash[:keys_data_id]
|
227
|
+
ins_data[:meta_values_data_id] = meta_hash[:values_data_id]
|
228
|
+
end
|
229
|
+
|
230
|
+
if args[:tag]
|
231
|
+
tag_value_id = @ob.static(:Log_data_value, :force_id, args[:tag])
|
232
|
+
ins_data[:tag_data_id] = tag_value_id
|
233
|
+
end
|
234
|
+
|
235
|
+
if args[:comment]
|
236
|
+
comment_value_id = @ob.static(:Log_data_value, :force_id, args[:comment])
|
237
|
+
ins_data[:comment_data_id] = comment_value_id
|
238
|
+
end
|
239
|
+
|
213
240
|
log_id = @db.insert(:Log, ins_data, {:return_id => true})
|
214
241
|
|
215
242
|
log_links = []
|
@@ -227,6 +254,7 @@ class Knjappserver
|
|
227
254
|
end
|
228
255
|
end
|
229
256
|
|
257
|
+
#Returns the HTML for a table with logs from a given object.
|
230
258
|
def logs_table(obj, args = {})
|
231
259
|
links = @ob.list(:Log_link, {"object_class" => obj.class.name, "object_id" => obj.id, "limit" => 500, "orderby" => [["id", "desc"]]})
|
232
260
|
|
@@ -235,8 +263,10 @@ class Knjappserver
|
|
235
263
|
html += "<tr>"
|
236
264
|
html += "<th>ID</th>"
|
237
265
|
html += "<th>Message</th>"
|
238
|
-
html += "<th>Date & time</th>"
|
266
|
+
html += "<th style=\"width: 130px;\">Date & time</th>"
|
267
|
+
html += "<th>Tag</th>"
|
239
268
|
html += "<th>Objects</th>" if args[:ob_use]
|
269
|
+
html += "<th>IP</th>" if args[:show_ip]
|
240
270
|
html += "</tr>"
|
241
271
|
html += "</thead>"
|
242
272
|
html += "<tbody>"
|
@@ -254,7 +284,17 @@ class Knjappserver
|
|
254
284
|
html += "<td>#{log.id}</td>"
|
255
285
|
html += "<td>#{first_line.html}</td>"
|
256
286
|
html += "<td>#{log.date_saved_str}</td>"
|
257
|
-
html += "<td>#{log.
|
287
|
+
html += "<td>#{log.tag.html}</td>"
|
288
|
+
|
289
|
+
if args[:ob_use]
|
290
|
+
begin
|
291
|
+
html += "<td>#{log.objects_html(args[:ob_use])}</td>"
|
292
|
+
rescue => e
|
293
|
+
html += "<td>#{e.message.html}</td>"
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
html += "<td>#{log.ip}</td>" if args[:show_ip]
|
258
298
|
html += "</tr>"
|
259
299
|
end
|
260
300
|
|
@@ -2,6 +2,9 @@ class Knjappserver
|
|
2
2
|
attr_reader :mails_waiting
|
3
3
|
|
4
4
|
def initialize_mailing
|
5
|
+
STDOUT.print "Loading mail.\n" if @config[:debug]
|
6
|
+
require "mail" if !@config.has_key?(:mail_require) or @config[:mail_require]
|
7
|
+
|
5
8
|
@mails_waiting = []
|
6
9
|
@mails_mutex = Mutex.new
|
7
10
|
@mails_queue_mutex = Mutex.new
|
@@ -10,6 +13,7 @@ class Knjappserver
|
|
10
13
|
end
|
11
14
|
end
|
12
15
|
|
16
|
+
#Queue a mail for sending. Possible keys are: :subject, :from, :to, :text and :html.
|
13
17
|
def mail(mail_args)
|
14
18
|
@mails_queue_mutex.synchronize do
|
15
19
|
count_wait = 0
|
@@ -23,11 +27,13 @@ class Knjappserver
|
|
23
27
|
end
|
24
28
|
|
25
29
|
mailobj = Knjappserver::Mail.new({:kas => self, :errors => {}, :status => :waiting}.merge(mail_args))
|
30
|
+
STDOUT.print "Added mail '#{mailobj.__id__}' to the mail-send-queue.\n" if debug
|
26
31
|
@mails_waiting << mailobj
|
27
32
|
return mailobj
|
28
33
|
end
|
29
34
|
end
|
30
35
|
|
36
|
+
#Sends all queued mails to the respective servers, if we are online.
|
31
37
|
def mail_flush
|
32
38
|
@mails_mutex.synchronize do
|
33
39
|
return false if @mails_waiting.length <= 0
|
@@ -55,41 +61,57 @@ class Knjappserver
|
|
55
61
|
end
|
56
62
|
end
|
57
63
|
|
64
|
+
#This class represents the queued mails.
|
58
65
|
class Mail
|
59
66
|
def initialize(args)
|
60
67
|
@args = args
|
61
68
|
|
62
69
|
raise "No knjappserver-object was given (as :kas)." if !@args[:kas].is_a?(Knjappserver)
|
63
70
|
raise "No :to was given." if !@args[:to]
|
64
|
-
|
71
|
+
raise "No content was given (:html or :text)." if !@args[:html] and !@args[:text]
|
65
72
|
end
|
66
73
|
|
74
|
+
#Returns a key from the arguments.
|
67
75
|
def [](key)
|
68
76
|
return @args[key]
|
69
77
|
end
|
70
78
|
|
79
|
+
#Sends the email to the receiver.
|
71
80
|
def send
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
STDOUT.print "Sending mail '#{__id__}'.\n" if @args[:kas].debug
|
82
|
+
|
83
|
+
begin
|
84
|
+
mail = Knj::Mailobj.new(@args[:kas].config[:smtp_args])
|
85
|
+
mail.to = @args[:to]
|
86
|
+
mail.subject = @args[:subject] if @args[:subject]
|
87
|
+
mail.html = @args[:html] if @args[:html]
|
88
|
+
mail.text = @args[:text] if @args[:text]
|
89
|
+
|
90
|
+
if @args[:from]
|
91
|
+
mail.from = @args[:from]
|
92
|
+
elsif @args[:kas].config[:error_report_from]
|
93
|
+
mail.from = @args[:kas].config[:error_report_from]
|
94
|
+
else
|
95
|
+
raise "Dont know where to take the 'from'-paramter from - none given in appserver config or mail-method-arguments?"
|
96
|
+
end
|
97
|
+
|
84
98
|
mail.send
|
85
99
|
@args[:status] = :sent
|
100
|
+
STDOUT.print "Sent email #{self.__id__}\n" if @args[:kas].debug
|
86
101
|
return true
|
87
|
-
rescue
|
102
|
+
rescue Exception => e
|
103
|
+
if @args[:kas].debug
|
104
|
+
STDOUT.print "Could not send email.\n"
|
105
|
+
STDOUT.puts e.inspect
|
106
|
+
STDOUT.puts e.backtrace
|
107
|
+
end
|
108
|
+
|
88
109
|
@args[:errors][e.class.name] = {:count => 0} if !@args[:errors].has_key?(e.class.name)
|
89
110
|
@args[:errors][e.class.name][:count] += 1
|
90
111
|
raise e if @args[:errors][e.class.name][:count] >= 5
|
91
112
|
@args[:status] = :error
|
92
113
|
@args[:error] = e
|
114
|
+
|
93
115
|
return false
|
94
116
|
end
|
95
117
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class Knjappserver
|
2
|
+
def initialize_sessions
|
3
|
+
@sessions = {}
|
4
|
+
end
|
5
|
+
|
6
|
+
#Returns or adds session based on idhash and meta-data.
|
7
|
+
def session_fromid(args)
|
8
|
+
ip = args[:ip].to_s
|
9
|
+
idhash = args[:idhash].to_s
|
10
|
+
ip = "bot" if idhash == "bot"
|
11
|
+
|
12
|
+
if !@sessions.key?(idhash)
|
13
|
+
session = @ob.get_by(:Session, {"idhash" => idhash})
|
14
|
+
if !session
|
15
|
+
session = @ob.add(:Session, {
|
16
|
+
:idhash => idhash,
|
17
|
+
:user_agent => args[:meta]["HTTP_USER_AGENT"],
|
18
|
+
:ip => ip
|
19
|
+
})
|
20
|
+
end
|
21
|
+
|
22
|
+
@sessions[idhash] = {
|
23
|
+
:dbobj => session,
|
24
|
+
:hash => {}
|
25
|
+
}
|
26
|
+
else
|
27
|
+
session = @sessions[idhash][:dbobj]
|
28
|
+
end
|
29
|
+
|
30
|
+
=begin
|
31
|
+
if ip != "bot"
|
32
|
+
if session[:user_agent] != args[:meta]["HTTP_USER_AGENT"]
|
33
|
+
STDOUT.print "Invalid user-agent!\n"
|
34
|
+
STDOUT.print Knj::Php.print_r(session, true)
|
35
|
+
|
36
|
+
raise Knj::Errors::InvalidData, "Invalid user-agent."
|
37
|
+
elsif !session.remember? and ip.to_s != session[:ip].to_s
|
38
|
+
STDOUT.print "Invalid IP!\n"
|
39
|
+
STDOUT.print Knj::Php.print_r(session, true)
|
40
|
+
|
41
|
+
raise Knj::Errors::InvalidData, "Invalid IP."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
=end
|
45
|
+
|
46
|
+
@sessions[idhash][:time_lastused] = Time.now
|
47
|
+
return @sessions[idhash]
|
48
|
+
end
|
49
|
+
|
50
|
+
#Generates a new session-ID by the meta data.
|
51
|
+
def session_generate_id(args)
|
52
|
+
meta = args[:meta]
|
53
|
+
return Digest::MD5.hexdigest("#{Time.now.to_f}_#{meta["HTTP_HOST"]}_#{meta["REMOTE_HOST"]}_#{meta["HTTP_X_FORWARDED_SERVER"]}_#{meta["HTTP_X_FORWARDED_FOR"]}_#{meta["HTTP_X_FORWARDED_HOST"]}_#{meta["REMOTE_ADDR"]}_#{meta["HTTP_USER_AGENT"]}")
|
54
|
+
end
|
55
|
+
|
56
|
+
#Will make the session rememberable for a year. IP wont be checked any more.
|
57
|
+
def session_remember
|
58
|
+
session = _httpsession.session
|
59
|
+
session[:remember] = 1
|
60
|
+
|
61
|
+
self.cookie(
|
62
|
+
"name" => "KnjappserverSession",
|
63
|
+
"value" => _httpsession.session_id,
|
64
|
+
"path" => "/",
|
65
|
+
"expires" => Time.now + 32140800 #add around 12 months
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
#Writes all session-data to the database (normally it is cached in memory and not updated on change).
|
70
|
+
def sessions_flush
|
71
|
+
if @sessions
|
72
|
+
@sessions.each do |session_hash, session_data|
|
73
|
+
STDOUT.print "Flushing session: #{session_data[:dbobj].id}\n" if @debug
|
74
|
+
session_data[:dbobj].flush
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -10,6 +10,13 @@ class Knjappserver
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
#Inits the thread so it has access to the appserver and various magic methods can be used.
|
14
|
+
def thread_init(thread)
|
15
|
+
thread[:knjappserver] = {} if !thread[:knjappserver]
|
16
|
+
thread[:knjappserver][:kas] = self
|
17
|
+
end
|
18
|
+
|
19
|
+
#Spawns a new thread with access to magic methods, _db-method and various other stuff in the appserver.
|
13
20
|
def thread(args = {})
|
14
21
|
raise "No block given." if !block_given?
|
15
22
|
args[:args] = [] if !args[:args]
|
@@ -34,53 +41,19 @@ class Knjappserver
|
|
34
41
|
end
|
35
42
|
end
|
36
43
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
while Thread.current[:knjappserver_timeout] > 0
|
49
|
-
Thread.current[:knjappserver_timeout] += -1
|
50
|
-
break if @should_restart
|
51
|
-
sleep 1
|
52
|
-
end
|
53
|
-
else
|
54
|
-
sleep args[:time]
|
55
|
-
end
|
56
|
-
|
57
|
-
break if @should_restart
|
58
|
-
|
59
|
-
@threadpool.run do
|
60
|
-
@ob.db.get_and_register_thread if @ob.db.opts[:threadsafe]
|
61
|
-
@db_handler.get_and_register_thread if @db_handler.opts[:threadsafe]
|
62
|
-
|
63
|
-
Thread.current[:knjappserver] = {
|
64
|
-
:kas => self,
|
65
|
-
:db => @db_handler
|
66
|
-
}
|
67
|
-
|
68
|
-
begin
|
69
|
-
yield(*args[:args])
|
70
|
-
ensure
|
71
|
-
@ob.db.free_thread if @ob.db.opts[:threadsafe]
|
72
|
-
@db_handler.free_thread if @db_handler.opts[:threadsafe]
|
73
|
-
end
|
74
|
-
end
|
75
|
-
rescue Exception => e
|
76
|
-
handle_error(e)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
return thread
|
44
|
+
#Runs a proc every number of seconds.
|
45
|
+
def timeout(args = {}, &block)
|
46
|
+
to = Knjappserver::Threadding_timeout.new(
|
47
|
+
:kas => self,
|
48
|
+
:block => block,
|
49
|
+
:args => args
|
50
|
+
)
|
51
|
+
to.start
|
52
|
+
|
53
|
+
return to
|
82
54
|
end
|
83
55
|
|
56
|
+
#Spawns a thread to run the given proc and add the output of that block in the correct order to the HTML.
|
84
57
|
def threadded_content(&block)
|
85
58
|
_httpsession.threadded_content(block)
|
86
59
|
end
|