maglev-webtools 0.2.1 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (296) hide show
  1. data/README.rdoc +38 -29
  2. data/bin/webtools +22 -1
  3. data/lib/web_tools/code_browser.rb +156 -0
  4. data/lib/web_tools/debugger.rb +96 -199
  5. data/lib/web_tools/info.rb +1 -3
  6. data/lib/web_tools/method_list.rb +67 -0
  7. data/lib/web_tools/middleware/debugger.rb +10 -16
  8. data/lib/web_tools/object_log.rb +24 -0
  9. data/lib/web_tools/session_list.rb +119 -0
  10. data/lib/web_tools/shared_page_cache.rb +30 -0
  11. data/lib/web_tools/stat_process.rb +24 -0
  12. data/lib/web_tools/statistics.rb +14 -0
  13. data/lib/web_tools/support/app_model.rb +66 -101
  14. data/lib/web_tools/support/code_browser.rb +88 -86
  15. data/lib/web_tools/support/debugger.rb +303 -0
  16. data/lib/web_tools/support/error_log.rb +33 -0
  17. data/lib/web_tools/support/ruby.rb +60 -121
  18. data/lib/web_tools/support/service_helper.rb +38 -10
  19. data/lib/web_tools/support/smalltalk_extensions.rb +12 -0
  20. data/lib/web_tools/tool.rb +48 -0
  21. data/lib/web_tools/ui.rb +14 -53
  22. data/lib/web_tools/version_report.rb +29 -0
  23. data/lib/web_tools/workspace.rb +77 -0
  24. data/lib/web_tools.rb +14 -4
  25. data/public/CodeBrowser.html +51 -0
  26. data/public/CodeMirror/LICENSE +19 -0
  27. data/public/CodeMirror/css/codemirror.css +67 -0
  28. data/public/CodeMirror/css/default.css +18 -0
  29. data/public/CodeMirror/js/codemirror.js +2131 -0
  30. data/public/CodeMirror/js/ruby.js +195 -0
  31. data/public/CodeMirror/js/smalltalk.js +139 -0
  32. data/public/Debugger.html +28 -0
  33. data/public/MethodList.html +20 -0
  34. data/public/ObjectLog.html +20 -0
  35. data/public/SessionList.html +31 -0
  36. data/public/SharedPageCache.html +78 -0
  37. data/public/Statistics.html +64 -0
  38. data/public/VersionReport.html +50 -0
  39. data/public/Workspace.html +39 -0
  40. data/public/css/CodeBrowser.css +24 -0
  41. data/public/css/Debugger.css +32 -0
  42. data/public/css/MethodList.css +8 -0
  43. data/public/css/ObjectLog.css +5 -0
  44. data/public/css/SessionList.css +9 -0
  45. data/public/css/Statistics.css +24 -0
  46. data/public/{stylesheets → css}/base/images/ui-anim_basic_16x16.gif +0 -0
  47. data/public/{stylesheets → css}/base/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  48. data/public/{stylesheets → css}/base/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  49. data/public/{stylesheets → css}/base/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  50. data/public/{stylesheets → css}/base/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  51. data/public/{stylesheets → css}/base/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  52. data/public/{stylesheets → css}/base/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  53. data/public/{stylesheets → css}/base/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  54. data/public/{stylesheets → css}/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  55. data/public/{stylesheets → css}/base/images/ui-icons_222222_256x240.png +0 -0
  56. data/public/{stylesheets → css}/base/images/ui-icons_2e83ff_256x240.png +0 -0
  57. data/public/{stylesheets → css}/base/images/ui-icons_454545_256x240.png +0 -0
  58. data/public/{stylesheets → css}/base/images/ui-icons_888888_256x240.png +0 -0
  59. data/public/{stylesheets → css}/base/images/ui-icons_cd0a0a_256x240.png +0 -0
  60. data/public/{stylesheets → css}/base/jquery.ui.accordion.css +0 -0
  61. data/public/{stylesheets → css}/base/jquery.ui.all.css +0 -0
  62. data/public/{stylesheets → css}/base/jquery.ui.autocomplete.css +0 -0
  63. data/public/{stylesheets → css}/base/jquery.ui.base.css +0 -0
  64. data/public/{stylesheets → css}/base/jquery.ui.button.css +0 -0
  65. data/public/{stylesheets → css}/base/jquery.ui.core.css +0 -0
  66. data/public/{stylesheets → css}/base/jquery.ui.datepicker.css +0 -0
  67. data/public/{stylesheets → css}/base/jquery.ui.dialog.css +0 -0
  68. data/public/{stylesheets → css}/base/jquery.ui.progressbar.css +0 -0
  69. data/public/{stylesheets → css}/base/jquery.ui.resizable.css +0 -0
  70. data/public/{stylesheets → css}/base/jquery.ui.selectable.css +0 -0
  71. data/public/{stylesheets → css}/base/jquery.ui.slider.css +0 -0
  72. data/public/{stylesheets → css}/base/jquery.ui.tabs.css +0 -0
  73. data/public/{stylesheets → css}/base/jquery.ui.theme.css +0 -0
  74. data/public/css/editor.css +25 -0
  75. data/public/css/jjmenu.css +33 -0
  76. data/public/css/menuitem.gif +0 -0
  77. data/public/css/more.gif +0 -0
  78. data/public/{stylesheets → css}/reset.css +1 -1
  79. data/public/css/smoothness/images/ui-anim_basic_16x16.gif +0 -0
  80. data/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  81. data/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  82. data/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  83. data/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  84. data/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  85. data/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  86. data/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  87. data/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  88. data/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  89. data/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  90. data/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  91. data/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  92. data/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  93. data/public/css/smoothness/jquery-ui.css +489 -0
  94. data/public/css/ui-lightness/images/ui-anim_basic_16x16.gif +0 -0
  95. data/public/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  96. data/public/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  97. data/public/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
  98. data/public/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  99. data/public/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  100. data/public/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  101. data/public/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  102. data/public/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  103. data/public/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  104. data/public/css/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
  105. data/public/css/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
  106. data/public/css/ui-lightness/images/ui-icons_ef8c08_256x240.png +0 -0
  107. data/public/css/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
  108. data/public/css/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
  109. data/public/css/ui-lightness/jquery-ui.css +489 -0
  110. data/public/css/webtools.css +65 -0
  111. data/public/favicon.ico +0 -0
  112. data/public/flot/API.txt +1201 -0
  113. data/public/flot/FAQ.txt +76 -0
  114. data/public/flot/LICENSE.txt +22 -0
  115. data/public/flot/Makefile +9 -0
  116. data/public/flot/NEWS.txt +508 -0
  117. data/public/flot/PLUGINS.txt +137 -0
  118. data/public/flot/README.txt +90 -0
  119. data/public/flot/examples/ajax.html +143 -0
  120. data/public/flot/examples/annotating.html +75 -0
  121. data/public/flot/examples/arrow-down.gif +0 -0
  122. data/public/flot/examples/arrow-left.gif +0 -0
  123. data/public/flot/examples/arrow-right.gif +0 -0
  124. data/public/flot/examples/arrow-up.gif +0 -0
  125. data/public/flot/examples/basic.html +38 -0
  126. data/public/flot/examples/data-eu-gdp-growth-1.json +4 -0
  127. data/public/flot/examples/data-eu-gdp-growth-2.json +4 -0
  128. data/public/flot/examples/data-eu-gdp-growth-3.json +4 -0
  129. data/public/flot/examples/data-eu-gdp-growth-4.json +4 -0
  130. data/public/flot/examples/data-eu-gdp-growth-5.json +4 -0
  131. data/public/flot/examples/data-eu-gdp-growth.json +4 -0
  132. data/public/flot/examples/data-japan-gdp-growth.json +4 -0
  133. data/public/flot/examples/data-usa-gdp-growth.json +4 -0
  134. data/public/flot/examples/graph-types.html +75 -0
  135. data/public/flot/examples/hs-2004-27-a-large_web.jpg +0 -0
  136. data/public/flot/examples/image.html +45 -0
  137. data/public/flot/examples/index.html +44 -0
  138. data/public/flot/examples/interacting-axes.html +97 -0
  139. data/public/flot/examples/interacting.html +93 -0
  140. data/public/flot/examples/layout.css +6 -0
  141. data/public/flot/examples/multiple-axes.html +60 -0
  142. data/public/flot/examples/navigate.html +118 -0
  143. data/public/flot/examples/percentiles.html +57 -0
  144. data/public/flot/examples/pie.html +756 -0
  145. data/public/flot/examples/realtime.html +83 -0
  146. data/public/flot/examples/resize.html +61 -0
  147. data/public/flot/examples/selection.html +114 -0
  148. data/public/flot/examples/setting-options.html +61 -0
  149. data/public/flot/examples/stacking.html +77 -0
  150. data/public/flot/examples/symbols.html +49 -0
  151. data/public/flot/examples/thresholding.html +54 -0
  152. data/public/flot/examples/time.html +71 -0
  153. data/public/flot/examples/tracking.html +95 -0
  154. data/public/flot/examples/turning-series.html +98 -0
  155. data/public/flot/examples/visitors.html +90 -0
  156. data/public/flot/examples/zooming.html +98 -0
  157. data/public/flot/excanvas.js +1427 -0
  158. data/public/flot/excanvas.min.js +1 -0
  159. data/public/flot/jquery.colorhelpers.js +179 -0
  160. data/public/flot/jquery.colorhelpers.min.js +1 -0
  161. data/public/flot/jquery.flot.crosshair.js +167 -0
  162. data/public/flot/jquery.flot.crosshair.min.js +1 -0
  163. data/public/flot/jquery.flot.fillbetween.js +183 -0
  164. data/public/flot/jquery.flot.fillbetween.min.js +1 -0
  165. data/public/flot/jquery.flot.image.js +238 -0
  166. data/public/flot/jquery.flot.image.min.js +1 -0
  167. data/public/flot/jquery.flot.js +2599 -0
  168. data/public/flot/jquery.flot.min.js +6 -0
  169. data/public/flot/jquery.flot.navigate.js +336 -0
  170. data/public/flot/jquery.flot.navigate.min.js +1 -0
  171. data/public/flot/jquery.flot.pie.js +750 -0
  172. data/public/flot/jquery.flot.pie.min.js +1 -0
  173. data/public/flot/jquery.flot.resize.js +60 -0
  174. data/public/flot/jquery.flot.resize.min.js +1 -0
  175. data/public/flot/jquery.flot.selection.js +344 -0
  176. data/public/flot/jquery.flot.selection.min.js +1 -0
  177. data/public/flot/jquery.flot.stack.js +184 -0
  178. data/public/flot/jquery.flot.stack.min.js +1 -0
  179. data/public/flot/jquery.flot.symbol.js +70 -0
  180. data/public/flot/jquery.flot.symbol.min.js +1 -0
  181. data/public/flot/jquery.flot.threshold.js +103 -0
  182. data/public/flot/jquery.flot.threshold.min.js +1 -0
  183. data/public/flot/jquery.js +8316 -0
  184. data/public/flot/jquery.min.js +23 -0
  185. data/public/genPacking.pl +30 -0
  186. data/public/index.html +28 -0
  187. data/public/install.tpz +66 -0
  188. data/public/installAndRun.tpz +5 -0
  189. data/public/jsTree/jquery.jstree.js +3510 -0
  190. data/public/jsTree/themes/default/d.gif +0 -0
  191. data/public/jsTree/themes/default/d.png +0 -0
  192. data/public/jsTree/themes/default/style.css +73 -0
  193. data/public/jsTree/themes/default/throbber.gif +0 -0
  194. data/public/readMe.txt +9 -0
  195. data/public/scripts/CodeBrowser.js +645 -0
  196. data/public/scripts/Debugger.js +134 -0
  197. data/public/scripts/MethodList.js +72 -0
  198. data/public/scripts/ObjectLog.js +59 -0
  199. data/public/scripts/SessionList.js +164 -0
  200. data/public/scripts/Statistics.js +266 -0
  201. data/public/scripts/editor.js +430 -0
  202. data/public/scripts/jjmenu.js +375 -0
  203. data/public/scripts/jquery-ui.js +1012 -0
  204. data/public/scripts/jquery.js +154 -0
  205. data/public/scripts/webtools.js +374 -0
  206. data/public/src/CodeBrowser.gs +416 -0
  207. data/public/src/Debugger.gs +132 -0
  208. data/public/src/MethodList.gs +130 -0
  209. data/public/src/ObjectLog.gs +73 -0
  210. data/public/src/Server.gs +544 -0
  211. data/public/src/SessionList.gs +172 -0
  212. data/public/src/SharedPageCache.gs +66 -0
  213. data/public/src/StatProcess.gs +280 -0
  214. data/public/src/StatProcessType.gs +242 -0
  215. data/public/src/StatStatistic.gs +381 -0
  216. data/public/src/Statistics.gs +222 -0
  217. data/public/src/Statmonitor.gs +490 -0
  218. data/public/src/Tool.gs +86 -0
  219. data/public/src/VersionReport.gs +52 -0
  220. data/public/src/Workspace.gs +163 -0
  221. data/views/debugger.rhtml +6 -9
  222. metadata +344 -243
  223. data/lib/web_tools/#debugger.rb# +0 -212
  224. data/lib/web_tools/browser.rb +0 -45
  225. data/public/images/favicon.ico +0 -0
  226. data/public/javascript/CodeMirror/LICENSE +0 -23
  227. data/public/javascript/CodeMirror/css/Smalltalk.css +0 -34
  228. data/public/javascript/CodeMirror/js/codemirror.js +0 -582
  229. data/public/javascript/CodeMirror/js/editor.js +0 -1671
  230. data/public/javascript/CodeMirror/js/highlight.js +0 -68
  231. data/public/javascript/CodeMirror/js/parseSmalltalk.js +0 -126
  232. data/public/javascript/CodeMirror/js/parsedummy.js +0 -32
  233. data/public/javascript/CodeMirror/js/select.js +0 -699
  234. data/public/javascript/CodeMirror/js/stringstream.js +0 -159
  235. data/public/javascript/CodeMirror/js/tokenize.js +0 -57
  236. data/public/javascript/CodeMirror/js/undo.js +0 -413
  237. data/public/javascript/CodeMirror/js/util.js +0 -133
  238. data/public/javascript/CodeMirror/testSmalltalkParser.html +0 -116
  239. data/public/javascript/ace/ace-uncompressed.js +0 -17299
  240. data/public/javascript/ace/ace.js +0 -1
  241. data/public/javascript/ace/keybinding-emacs.js +0 -1
  242. data/public/javascript/ace/keybinding-vim.js +0 -1
  243. data/public/javascript/ace/mode-c_cpp.js +0 -1
  244. data/public/javascript/ace/mode-clojure.js +0 -1
  245. data/public/javascript/ace/mode-coffee.js +0 -1
  246. data/public/javascript/ace/mode-csharp.js +0 -1
  247. data/public/javascript/ace/mode-css.js +0 -1
  248. data/public/javascript/ace/mode-groovy.js +0 -1
  249. data/public/javascript/ace/mode-html.js +0 -1
  250. data/public/javascript/ace/mode-java.js +0 -1
  251. data/public/javascript/ace/mode-javascript.js +0 -1
  252. data/public/javascript/ace/mode-json.js +0 -1
  253. data/public/javascript/ace/mode-lua.js +0 -1
  254. data/public/javascript/ace/mode-markdown.js +0 -1
  255. data/public/javascript/ace/mode-ocaml.js +0 -1
  256. data/public/javascript/ace/mode-perl.js +0 -1
  257. data/public/javascript/ace/mode-php.js +0 -1
  258. data/public/javascript/ace/mode-python.js +0 -1
  259. data/public/javascript/ace/mode-ruby.js +0 -1
  260. data/public/javascript/ace/mode-scad.js +0 -1
  261. data/public/javascript/ace/mode-scala.js +0 -1
  262. data/public/javascript/ace/mode-scss.js +0 -1
  263. data/public/javascript/ace/mode-svg.js +0 -1
  264. data/public/javascript/ace/mode-textile.js +0 -1
  265. data/public/javascript/ace/mode-xml.js +0 -1
  266. data/public/javascript/ace/theme-clouds.js +0 -1
  267. data/public/javascript/ace/theme-clouds_midnight.js +0 -1
  268. data/public/javascript/ace/theme-cobalt.js +0 -1
  269. data/public/javascript/ace/theme-crimson_editor.js +0 -1
  270. data/public/javascript/ace/theme-dawn.js +0 -1
  271. data/public/javascript/ace/theme-eclipse.js +0 -1
  272. data/public/javascript/ace/theme-idle_fingers.js +0 -1
  273. data/public/javascript/ace/theme-kr_theme.js +0 -1
  274. data/public/javascript/ace/theme-merbivore.js +0 -1
  275. data/public/javascript/ace/theme-merbivore_soft.js +0 -1
  276. data/public/javascript/ace/theme-mono_industrial.js +0 -1
  277. data/public/javascript/ace/theme-monokai.js +0 -1
  278. data/public/javascript/ace/theme-pastel_on_dark.js +0 -1
  279. data/public/javascript/ace/theme-solarized_dark.js +0 -1
  280. data/public/javascript/ace/theme-solarized_light.js +0 -1
  281. data/public/javascript/ace/theme-textmate.js +0 -1
  282. data/public/javascript/ace/theme-twilight.js +0 -1
  283. data/public/javascript/ace/theme-vibrant_ink.js +0 -1
  284. data/public/javascript/ace/worker-coffee.js +0 -1
  285. data/public/javascript/ace/worker-css.js +0 -1
  286. data/public/javascript/ace/worker-javascript.js +0 -1
  287. data/public/javascript/webtools/browser.js +0 -260
  288. data/public/javascript/webtools/debugger.coffee +0 -286
  289. data/public/javascript/webtools/debugger.js +0 -366
  290. data/public/javascript/webtools/sessions.coffee +0 -17
  291. data/public/javascript/webtools/sessions.js +0 -27
  292. data/public/javascript/webtools/version.coffee +0 -14
  293. data/public/javascript/webtools/version.js +0 -20
  294. data/public/stylesheets/jquery.contextMenu.css +0 -62
  295. data/public/stylesheets/webtools.css +0 -53
  296. data/public/test.html +0 -47
@@ -3,9 +3,7 @@ require 'web_tools'
3
3
  require 'web_tools/support/app_model'
4
4
  require 'web_tools/support/service_helper'
5
5
 
6
- class WebTools::Info < Sinatra::Base
7
- include WebTools::Support::ServiceHelper
8
-
6
+ class WebTools::Info < WebTools::Tool
9
7
  before do
10
8
  @ts = Time.now
11
9
  @stack = nil
@@ -0,0 +1,67 @@
1
+ require 'sinatra/base'
2
+ require 'web_tools'
3
+ require 'web_tools/support/service_helper'
4
+
5
+ class WebTools::MethodList < WebTools::Tool
6
+ dont_show!
7
+
8
+ def self.description
9
+ super
10
+ end
11
+
12
+ get '/' do
13
+ json(execute(params["type"]))
14
+ end
15
+
16
+ def execute(meth)
17
+ callables = { "method" => method(:find_method),
18
+ "implementors" => method(:implementors),
19
+ "senders" => method(:senders),
20
+ "referencesToGlobal" => method(:references_to_global) }
21
+ callable = callables[meth]
22
+ return {"a" => "AAA"} if callable.nil?
23
+ callable[]
24
+ end
25
+
26
+ def find_method
27
+ name = non_meta_name(params["klass"])
28
+ is_meta = !(name == params["klass"])
29
+ klass = reflect(Object).constant(name).value
30
+ klass = klass.singleton_class if is_meta
31
+ meth = klass.method(params["selector"])
32
+ { "dictionaryName" => params["dict"],
33
+ "className" => klass.name,
34
+ "isMeta" => is_meta,
35
+ "source" => meth.source,
36
+ "stepPoints" => meth.step_offsets,
37
+ "sends" => meth.send_offsets }
38
+ end
39
+
40
+ def implementors
41
+ return {} unless params["find"]
42
+ methods(system.implementations_of(params["find"]))
43
+ end
44
+
45
+ def senders
46
+ return {} unless params["find"]
47
+ methods(system.senders_of(params["find"]))
48
+ end
49
+
50
+ def references_to_global
51
+ return {} # Not supported on Ruby, too dynamic
52
+ end
53
+
54
+ def methods(list)
55
+ list = list.collect do |meth|
56
+ klass = meth.defining_class
57
+ nesting = klass.nesting
58
+ dict = nesting[1] ? nesting[1].name : "" # [klass, parent, ...]
59
+ { "dict" => dict,
60
+ "klassCat" => "",
61
+ "klass" => klass.name,
62
+ "category" => "",
63
+ "selector" => meth.selector }
64
+ end
65
+ { "list" => list }
66
+ end
67
+ end
@@ -1,5 +1,5 @@
1
1
  require 'web_tools'
2
- require 'maglev/debugger'
2
+ # require 'maglev/debugger'
3
3
 
4
4
  module WebTools::Middleware
5
5
  class Debugger
@@ -49,20 +49,14 @@ module WebTools::Middleware
49
49
  end
50
50
 
51
51
  def debugger_active?
52
- defined?(@@debugger_active) && !!@@debugger_active &&
53
- defined?(@@debugged_process) && @@debugged_process.alive?
52
+ defined?(@@debugger_active) && !!@@debugger_active
54
53
  end
55
54
 
56
55
  def wrap_call(env)
57
56
  if debugger_active?
58
- p env
59
- if env["PATH_INFO"] == "/"
60
- [500, {"Content-Type" => "text/html"}, info_message(env)]
61
- else
62
- response = @debugger_app.call(env)
63
- response[1]['Access-Control-Allow-Origin'] = "*"
64
- response
65
- end
57
+ response = @debugger_app.call(env)
58
+ response[1]['Access-Control-Allow-Origin'] = "*"
59
+ response
66
60
  else
67
61
  application_call(env, yield)
68
62
  end
@@ -73,7 +67,7 @@ module WebTools::Middleware
73
67
  raise result.exception if result[:skip_debugger]
74
68
  result[:skip_debugger] = false
75
69
  @@debugged_path = env["PATH_INFO"]
76
- @@debugged_process = result.thread
70
+ @@debugged_process = result.thread.object_id
77
71
  @@debugger_active = true
78
72
  @@debugged_exception = result.exception.message
79
73
  [500, {"Content-Type" => "text/html"}, info_message(env)]
@@ -87,7 +81,7 @@ module WebTools::Middleware
87
81
  env['rack.url_scheme'].to_s + "://" +
88
82
  env['HTTP_HOST'].to_s +
89
83
  env['SCRIPT_NAME'].to_s + "/process/" +
90
- @@debugged_process.object_id.to_s)]
84
+ @@debugged_process.to_s)]
91
85
  end
92
86
  end
93
87
  end
@@ -109,9 +103,9 @@ __END__
109
103
  <a href="<%= path %>"><%= path %></a>
110
104
  <br>
111
105
  Once you're done debugging, you can click
112
- <form style="display:inline" name="resumeForm" method="POST" action="<%= path %>">
113
- <input type="hidden" name="running" VALUE="true">
114
- <a href="#" onClick="document.resumeForm.submit(); return false">here</a>
106
+ <form style="display:inline" name="resumeForm" method="PUT" action="<%= path %>">
107
+ <input type="hidden" name="resume" VALUE="">
108
+ <a href="#" onClick="document.resumeForm.submit();return false">here</a>
115
109
  </form>
116
110
  to resume the original process.
117
111
  </body>
@@ -0,0 +1,24 @@
1
+ require 'sinatra/base'
2
+ require 'web_tools'
3
+ require 'web_tools/support/app_model'
4
+ require 'web_tools/support/service_helper'
5
+ require 'maglev/objectlog'
6
+
7
+ class WebTools::ObjectLog < WebTools::Tool
8
+ get '/' do
9
+ list = ObjectLog.to_ary.reverse.collect do |entry|
10
+ label = "#{entry.label}"
11
+ object_str = "#{entry.object}"
12
+ label = label.split.first if label == object_str
13
+ { "oop" => entry.object_id,
14
+ "stamp" => entry.timestamp.to_s,
15
+ "pid" => entry.pid.to_s,
16
+ "label" => label,
17
+ "type" => %w[Fatal Error Warn Info Debug Trace Transcript][entry.priority-1],
18
+ "tag" => "#{entry.tag if entry.tagged?}",
19
+ "object" => object_str,
20
+ "hasContinuation" => entry.has_cc? }
21
+ end
22
+ json("list" => list)
23
+ end
24
+ end
@@ -0,0 +1,119 @@
1
+ require 'sinatra/base'
2
+ require 'web_tools'
3
+ require 'web_tools/support/service_helper'
4
+
5
+ class WebTools::SessionList < WebTools::Tool
6
+ def self.description
7
+ 'Information about current sessions and other processes'
8
+ end
9
+
10
+ get '/' do
11
+ json("labels" => SessionListLabels,
12
+ "sessions" => session_list,
13
+ "other" => non_session_list)
14
+ end
15
+
16
+ get '/statsForSlot' do
17
+ slot = params["slot"]
18
+ statistics = Maglev::System.cache_statistics(slot.to_i).to_a
19
+ descriptions = Maglev::System.cache_statistics_description_for_type statistics[3]
20
+ result = []
21
+ bytes = []
22
+ descriptions.size.times do |idx|
23
+ name = descriptions[idx]
24
+ metadata = Maglev::System::StatStatistic.cache_stat_descriptions["name"] ||
25
+ ['' '' '' '' '']
26
+ result.push("name" => name,
27
+ "type" => metadata[1],
28
+ "level" => metadata[2],
29
+ "units" => metadata[3],
30
+ "isOs" => metadata[4],
31
+ "value" => statistics[idx])
32
+ end
33
+ topFour = result[0..3]
34
+ result = result[4..-1].sort_by {|a| a["name"] }
35
+ json("stats" => topFour + result)
36
+ end
37
+
38
+ get '/cacheDescription' do
39
+ name = params["name"]
40
+ cache = Maglev::System::StatStatistic.cache_stat_descriptions
41
+ details = cache["name"] || ["No description available for #{name}"]
42
+ json("description" => details.first)
43
+ end
44
+
45
+ # Returns a hash of configuration parameters for the stone and the gem.
46
+ # The has has three keys:
47
+ # + :timestamp => when the report was generated
48
+ # + :headers => array of [name, description] pairs for the fields
49
+ # + :report => An array of data. Each entry is an array of the field data.
50
+ #
51
+ def session_list
52
+ ts = Time.now
53
+ now = ts.to_i
54
+ session_info = Maglev::System.current_session_ids.map do |id|
55
+ sess_desc = Maglev::System.description_of_session id
56
+ sess_desc[0] = sess_desc[0].instance_variable_get(:@_st_userId) # UserProfile
57
+ sess_desc[3] = '' if sess_desc[3] == 0 # Primitive?
58
+ sess_desc[4] = format_secs(now - sess_desc[4]) # View Age
59
+ sess_desc[6] = ['none', 'out', 'in'][sess_desc[6] + 1] # Transaction
60
+ sess_desc[13] = format_secs(now - sess_desc[13]) # Quiet
61
+ sess_desc[14] = format_secs(now - sess_desc[14]) # Age
62
+ sess_desc
63
+ # sess_cache_slot = Maglev::System.cache_slot_for_sessionid id
64
+ end
65
+ session_info
66
+ end
67
+
68
+ def non_session_list
69
+ begin
70
+ sessions = Maglev::System.current_session_ids.to_a
71
+ slots = []
72
+ 1000.times do |slot| # Any number will do, theres a limited number of slots
73
+ ary = Maglev::System.cache_statistics(slot).to_a
74
+ unless sessions.include?(ary[2])
75
+ slots << [slot, ary.first]
76
+ end
77
+ end
78
+ rescue Exception
79
+ return slots
80
+ end
81
+ end
82
+
83
+ SECS_PER_DAY = 86400
84
+ SECS_PER_HOUR = 3600
85
+ SECS_PER_MIN = 60
86
+ SECS_PER_SEC = 1
87
+
88
+ # Format number of seconds like "3 days 12:07:58"
89
+ def format_secs(seconds)
90
+ splits = []
91
+ [SECS_PER_DAY, SECS_PER_HOUR, SECS_PER_MIN, SECS_PER_SEC].each do |x|
92
+ splits << seconds / x
93
+ seconds = seconds % x
94
+ end
95
+ days = splits.shift
96
+
97
+ ts = "%02d:%02d:%02d" % splits
98
+ days > 0 ? "#{days} #{days == 1 ? 'day' : 'days'} #{ts}" : ts
99
+ end
100
+
101
+ # See System class>>#'descriptionOfSession:'
102
+ SessionListLabels = [['User', 'UserProfile of the session, or nil if the UserProfile is recently created and not visible from this session''s transactional view, or the session is no longer active.'],
103
+ ['PID', 'The process ID of the Gem process of the session.'],
104
+ ['Host', 'The hostname of the machine running the Gem process (a String, limited to 127 bytes).'],
105
+ ['Prim', 'Primitive number in which the Gem is executing (if it is executing in a long primitive such as MFC).'],
106
+ ['View Age', 'Time since the session''s most recent beginTransaction, commitTransaction, or abortTransaction.'],
107
+ ['State', 'The session state (an enum from SesTaskStatusEType in session.ht).'],
108
+ ['Trans', 'One of the following: ''none'' if the session is in transactionless mode, ''out'' if it is not in a transaction, and ''in'' if it is in a transaction.'],
109
+ ['Oldest CR', 'A Boolean whose value is true if the session is currently referencing the oldest commit record, and false if it is not.'],
110
+ ['Serial', 'The session''s serial number. A serial number will not be reused until the stone is restarted.'],
111
+ ['Session', "The session''s sessionId. The configured maximum is #{Maglev::System.max_session_id} for this stone."],
112
+ ['GCI IP', 'A String containing the ip address of host running the GCI process. If the GCI application is linked (using libgcilnk*.so or gcilnk*.dll) this ip address is the address of the machine running the gem process.'],
113
+ ['Priority', 'The priority of the session where 0 is lowest, 2 is normal, and 4 is highest. Session priority is used by the stone to order requests for service by sessions.'],
114
+ ['Host ID', 'Unique host ID of the host where the session is running.'],
115
+ ['Quiet', 'Time since the session''s most recent request to stone.'],
116
+ ['Age', 'Time since the session logged in.'],
117
+ ['CRB', 'Commit Record Backlog: number of commits which have occurred since the session obtained its view.'],
118
+ ['Slot', 'The session''s cache process slot number if it is connected to the same shared page cache as Server. A return of nil indicates the session could not be located (so the gem is likely on another host).']]
119
+ end
@@ -0,0 +1,30 @@
1
+ require 'sinatra/base'
2
+ require 'web_tools'
3
+ # require 'web_tools/support/app_model'
4
+ # require 'web_tools/support/service_helper'
5
+
6
+ class WebTools::SharedPageCache < WebTools::Tool
7
+ def self.description
8
+ "Information about the Shared Page Cache"
9
+ end
10
+
11
+ get '/' do
12
+ values = Maglev::System.cache_statistics(0) # SPC Monitor
13
+ descrs = Maglev::System.cache_statistics_description_for_type(values[3])
14
+
15
+ stats = Hash[descrs.zip(values)]
16
+ size = stats["FrameCount"].to_f
17
+ free = stats["FreeFrameCount"]
18
+ globalDirty = stats["GlobalDirtyPageCount"]
19
+ localDirty = stats["LocalDirtyPageCount"]
20
+ json("objectTable" => (stats["TotalOtPages"] / size * 100).round,
21
+ "bitmap" => (stats["TotalBitmapPages"] / size * 100).round,
22
+ "commitRecord" => (stats["TotalCrPages"] / size * 100).round,
23
+ "other" => (stats["TotalOtherPages"] / size * 100).round,
24
+ "data" => (stats["TotalDataPages"] / size * 100).round,
25
+ "free" => (free / size * 100).round,
26
+ "globalDirty" => (globalDirty / size * 100).round,
27
+ "localDirty" => (localDirty / size * 100).round,
28
+ "clean" => ((size - localDirty - globalDirty - free) / size * 100).round)
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ require 'sinatra/base'
2
+ require 'web_tools'
3
+ require 'web_tools/support/app_model'
4
+ require 'web_tools/support/service_helper'
5
+ require 'maglev/objectlog'
6
+
7
+ class WebTools::ObjectLog < WebTools::Tool
8
+ get '/' do
9
+ list = ObjectLog.to_a.reverse.collect do |entry|
10
+ label = "#{entry.label}"
11
+ object_str = "#{entry.object}"
12
+ label = label.split.first if label == object_str
13
+ { "oop" => entry.object_id,
14
+ "stamp" => entry.timestamp.to_s,
15
+ "pid" => entry.pid.to_s,
16
+ "label" => label,
17
+ "type" => %w[Fatal Error Warn Info Debug Trace Transcript][entry.priority],
18
+ "tag" => "#{entry.tag if entry.tagged?}",
19
+ "object" => object_str,
20
+ "hasContinuation" => entry.has_cc? }
21
+ end
22
+ json("list" => list)
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ require 'sinatra/base'
2
+ require 'web_tools'
3
+ require 'web_tools/support/app_model'
4
+ require 'web_tools/support/service_helper'
5
+
6
+ class WebTools::Statistics < WebTools::Tool
7
+ def self.description
8
+ "Load and view statmonitor files"
9
+ end
10
+
11
+ get '/' do
12
+ json("files" => [])
13
+ end
14
+ end
@@ -4,114 +4,79 @@ require 'web_tools/support/smalltalk_extensions'
4
4
 
5
5
  # This module emulates all of the API from the Smalltalk side of things
6
6
  module WebTools
7
-
8
- # This is a ViewModel for the WebTools Application.
9
- #
10
- # All of the methods that return "Objects" should return a Hash. Keys
11
- # beginning with '_' are reserved for metadata applied by the GUI.
12
- class AppModel
13
- def initialize
14
- end
15
-
16
- VERSION_HEADERS = [['Attribute', 'The attribute.'],
17
- ['Stone', 'The value for the stone process.'],
18
- ['WebTools', 'The value for the WebTools vm process (if different than the Stone''s value)']]
19
-
20
-
21
- # Returns a hash of configuration parameters for the stone and the gem.
22
- # The has has three keys:
23
- # + :timestamp => when the report was generated
24
- # + :headers => array of [name, description] pairs for the fields
25
- # + :report => An array of data. Each entry is an array of the field data.
26
- #
27
- def version_report
28
- stone_rpt = stone_version_report
29
- gem_rpt = gem_version_report
30
- data = { }
31
- (stone_rpt.keys + gem_rpt.keys).each do |k|
32
- g = stone_rpt[k] == gem_rpt[k] ? '' : gem_rpt[k]
33
- data[k] = [stone_rpt[k], g]
34
- end
35
- { :timestamp => Time.now.asctime,
36
- :headers => VERSION_HEADERS,
37
- :report => data }
38
- end
39
-
40
- # An array of [name, description] entries for the fields in the session report.
41
- SESSION_FIELDS =
42
- [['User', 'The UserProfile of the session, or nil if the UserProfile is recently created and not visible from this session''s transactional view, or the session is no longer active.'],
43
- ['PID', 'The process ID of the Gem process of the session.'],
44
- ['Host', 'The hostname of the machine running the Gem process (a String, limited to 127 bytes).'],
45
- ['Prim #', 'Primitive number in which the Gem is executing (if it is executing in a long primitive such as MFC).'],
46
- ['View Age', 'Time since the session''s most recent beginTransaction, commitTransaction, or abortTransaction.'],
47
- ['State', 'The session state (an enum from SesTaskStatusEType in session.ht).'],
48
- ['Trans', 'One of the following: ''none'' if the session is in transactionless mode, ''out'' if it is not in a transaction, and ''in'' if it is in a transaction.'],
49
- ['Oldest CR?', 'A Boolean whose value is true if the session is currently referencing the oldest commit record, and false if it is not.'],
50
- ['Serial', 'The session''s serial number. A serial number will not be reused until the stone is restarted.'],
51
- ['Session', "The session's sessionId."],
52
- ['GCI IP', 'A String containing the ip address of host running the GCI process. If the GCI application is linked (using libgcilnk*.so or gcilnk*.dll) this ip address is the address of the machine running the gem process.'],
53
- ['Priority', 'The priority of the session where 0 is lowest, 2 is normal, and 4 is highest. Session priority is used by the stone to order requests for service by sessions.'],
54
- ['Host ID', 'Unique host ID of the host where the session is running.'],
55
- ['Quiet', 'Time since the session''s most recent request to stone.'],
56
- ['Age', 'Time since the session logged in.'],
57
- ['CRB', 'Commit Record Backlog: number of commits which have occurred since the session obtained its view.']]
58
-
59
- # Returns a hash of configuration parameters for the stone and the gem.
60
- # The has has three keys:
61
- # + :timestamp => when the report was generated
62
- # + :headers => array of [name, description] pairs for the fields
63
- # + :report => An array of data. Each entry is an array of the field data.
7
+ module Support
8
+ # This is a ViewModel for the WebTools Application.
64
9
  #
65
- def session_report
66
- ts = Time.now
67
- now = ts.to_i
68
- session_info = Maglev::System.current_session_ids.map do |id|
69
- sess_desc = Maglev::System.description_of_session id
70
- sess_desc[0] = sess_desc[0].instance_variable_get(:@_st_userId) # UserProfile
71
- sess_desc[3] = '' if sess_desc[3] == 0 # Primitive?
72
- sess_desc[4] = format_secs(now - sess_desc[4]) # View Age
73
- sess_desc[6] = ['none', 'out', 'in'][sess_desc[6] + 1] # Transaction
74
- sess_desc[13] = format_secs(now - sess_desc[13]) # Quiet
75
- sess_desc[14] = format_secs(now - sess_desc[14]) # Age
76
- sess_desc
77
- # sess_cache_slot = Maglev::System.cache_slot_for_sessionid id
78
- end
79
- { :timestamp => ts.asctime,
80
- :headers => SESSION_FIELDS,
81
- :report => session_info }
82
- end
10
+ # All of the methods that return "Objects" should return a Hash. Keys
11
+ # beginning with '_' are reserved for metadata applied by the GUI.
12
+ module AppModel
13
+ extend self
83
14
 
15
+ VERSION_HEADERS = [['Attribute', 'The attribute.'],
16
+ ['Stone', 'The value for the stone process.'],
17
+ ['WebTools', 'The value for the WebTools vm process (if different than the Stone''s value)']]
84
18
 
85
- SECS_PER_DAY = 86400
86
- SECS_PER_HOUR = 3600
87
- SECS_PER_MIN = 60
88
- SECS_PER_SEC = 1
89
19
 
90
- # Format number of seconds like "3 days 12:07:58"
91
- def format_secs(seconds)
92
- splits = []
93
- [SECS_PER_DAY, SECS_PER_HOUR, SECS_PER_MIN, SECS_PER_SEC].each do |x|
94
- splits << seconds / x
95
- seconds = seconds % x
20
+ # Returns a hash of configuration parameters for the stone and the gem.
21
+ # The has has three keys:
22
+ # + :timestamp => when the report was generated
23
+ # + :headers => array of [name, description] pairs for the fields
24
+ # + :report => An array of data. Each entry is an array of the field data.
25
+ #
26
+ def version_report
27
+ stone_rpt = stone_version_report
28
+ gem_rpt = gem_version_report
29
+ data = { }
30
+ (stone_rpt.keys + gem_rpt.keys).each do |k|
31
+ g = stone_rpt[k] == gem_rpt[k] ? '' : gem_rpt[k]
32
+ data[k] = [stone_rpt[k], g]
33
+ end
34
+ { :timestamp => Time.now.asctime,
35
+ :headers => VERSION_HEADERS,
36
+ :report => data }
96
37
  end
97
- days = splits.shift
98
38
 
99
- ts = "%02d:%02d:%02d" % splits
100
- days > 0 ? "#{days} #{days == 1 ? 'day' : 'days'} #{ts}" : ts
101
- end
102
-
103
- def stone_version_report
104
- results = { }
105
- rpt = Maglev::System.stone_version_report
106
- rpt.keys.each { |k| results[k] = rpt.at(k) }
107
- results
108
- end
39
+ # An array of [name, description] entries for the fields in the session report.
40
+ SESSION_FIELDS =
41
+ [['User', 'The UserProfile of the session, or nil if the UserProfile is recently created and not visible from this session''s transactional view, or the session is no longer active.'],
42
+ ['PID', 'The process ID of the Gem process of the session.'],
43
+ ['Host', 'The hostname of the machine running the Gem process (a String, limited to 127 bytes).'],
44
+ ['Prim #', 'Primitive number in which the Gem is executing (if it is executing in a long primitive such as MFC).'],
45
+ ['View Age', 'Time since the session''s most recent beginTransaction, commitTransaction, or abortTransaction.'],
46
+ ['State', 'The session state (an enum from SesTaskStatusEType in session.ht).'],
47
+ ['Trans', 'One of the following: ''none'' if the session is in transactionless mode, ''out'' if it is not in a transaction, and ''in'' if it is in a transaction.'],
48
+ ['Oldest CR?', 'A Boolean whose value is true if the session is currently referencing the oldest commit record, and false if it is not.'],
49
+ ['Serial', 'The session''s serial number. A serial number will not be reused until the stone is restarted.'],
50
+ ['Session', "The session's sessionId."],
51
+ ['GCI IP', 'A String containing the ip address of host running the GCI process. If the GCI application is linked (using libgcilnk*.so or gcilnk*.dll) this ip address is the address of the machine running the gem process.'],
52
+ ['Priority', 'The priority of the session where 0 is lowest, 2 is normal, and 4 is highest. Session priority is used by the stone to order requests for service by sessions.'],
53
+ ['Host ID', 'Unique host ID of the host where the session is running.'],
54
+ ['Quiet', 'Time since the session''s most recent request to stone.'],
55
+ ['Age', 'Time since the session logged in.'],
56
+ ['CRB', 'Commit Record Backlog: number of commits which have occurred since the session obtained its view.']]
109
57
 
110
- def gem_version_report
111
- results = { }
112
- rpt = Maglev::System.gem_version_report
113
- rpt.keys.each { |k| results[k] = rpt.at(k) }
114
- results
58
+ # Returns a hash of configuration parameters for the stone and the gem.
59
+ # The has has three keys:
60
+ # + :timestamp => when the report was generated
61
+ # + :headers => array of [name, description] pairs for the fields
62
+ # + :report => An array of data. Each entry is an array of the field data.
63
+ #
64
+ def session_report
65
+ ts = Time.now
66
+ now = ts.to_i
67
+ session_info = Maglev::System.current_session_ids.map do |id|
68
+ sess_desc = Maglev::System.description_of_session id
69
+ sess_desc[0] = sess_desc[0].instance_variable_get(:@_st_userId) # UserProfile
70
+ sess_desc[3] = '' if sess_desc[3] == 0 # Primitive?
71
+ sess_desc[4] = format_secs(now - sess_desc[4]) # View Age
72
+ sess_desc[6] = ['none', 'out', 'in'][sess_desc[6] + 1] # Transaction
73
+ sess_desc[13] = format_secs(now - sess_desc[13]) # Quiet
74
+ sess_desc[14] = format_secs(now - sess_desc[14]) # Age
75
+ sess_desc
76
+ # sess_cache_slot = Maglev::System.cache_slot_for_sessionid id
77
+ end
78
+ session_info
79
+ end
115
80
  end
116
81
  end
117
82
  end