plezi 0.12.22 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/LICENSE.txt +17 -18
  4. data/README.md +54 -698
  5. data/Rakefile +7 -4
  6. data/bin/config.ru +22 -0
  7. data/{test → bin}/console +4 -6
  8. data/bin/hello_world +52 -0
  9. data/bin/setup +8 -0
  10. data/exe/plezi +145 -0
  11. data/lib/plezi.rb +24 -137
  12. data/lib/plezi/activation.rb +28 -0
  13. data/lib/plezi/api.rb +62 -0
  14. data/lib/plezi/controller/controller.rb +259 -0
  15. data/lib/plezi/controller/controller_class.rb +176 -0
  16. data/lib/plezi/controller/cookies.rb +40 -0
  17. data/lib/plezi/helpers.rb +60 -0
  18. data/lib/plezi/rake.rb +2 -24
  19. data/lib/plezi/render/erb.rb +34 -0
  20. data/lib/plezi/render/has_cache.rb +36 -0
  21. data/lib/plezi/render/markdown.rb +63 -0
  22. data/lib/plezi/render/render.rb +49 -0
  23. data/lib/plezi/render/sass.rb +55 -0
  24. data/lib/plezi/render/slim.rb +33 -0
  25. data/lib/plezi/router/adclient.rb +23 -0
  26. data/lib/plezi/router/assets.rb +67 -0
  27. data/lib/plezi/router/errors.rb +29 -0
  28. data/lib/plezi/router/route.rb +112 -0
  29. data/lib/plezi/router/router.rb +120 -0
  30. data/lib/plezi/version.rb +1 -1
  31. data/lib/plezi/websockets/message_dispatch.rb +91 -0
  32. data/lib/plezi/websockets/redis.rb +55 -0
  33. data/plezi.gemspec +25 -16
  34. data/resources/404.erb +5 -4
  35. data/resources/500.erb +5 -4
  36. data/resources/{500.html → 503.html} +8 -9
  37. data/resources/client.js +253 -0
  38. data/resources/config.ru +5 -36
  39. data/resources/ctrlr.rb +34 -0
  40. data/resources/gemfile +4 -0
  41. data/resources/mini_app.rb +28 -82
  42. data/resources/mini_exec +7 -0
  43. data/resources/mini_welcome_page.html +0 -0
  44. data/resources/procfile +3 -0
  45. data/resources/rakefile +4 -8
  46. data/resources/routes.rb +9 -26
  47. data/resources/{websockets.js → simple-client.js} +3 -3
  48. metadata +60 -85
  49. data/bin/plezi +0 -104
  50. data/docs/async_helpers.md +0 -245
  51. data/docs/controllers.md +0 -27
  52. data/docs/logging.md +0 -49
  53. data/docs/routes.md +0 -209
  54. data/docs/websockets.md +0 -213
  55. data/lib/plezi/builders/ac_model.rb +0 -59
  56. data/lib/plezi/builders/app_builder.rb +0 -137
  57. data/lib/plezi/builders/builder.rb +0 -43
  58. data/lib/plezi/builders/form_builder.rb +0 -27
  59. data/lib/plezi/common/api.rb +0 -92
  60. data/lib/plezi/common/cache.rb +0 -122
  61. data/lib/plezi/common/defer.rb +0 -21
  62. data/lib/plezi/common/dsl.rb +0 -94
  63. data/lib/plezi/common/redis.rb +0 -65
  64. data/lib/plezi/common/renderer.rb +0 -141
  65. data/lib/plezi/common/settings.rb +0 -52
  66. data/lib/plezi/handlers/controller_core.rb +0 -106
  67. data/lib/plezi/handlers/controller_magic.rb +0 -284
  68. data/lib/plezi/handlers/http_router.rb +0 -205
  69. data/lib/plezi/handlers/placebo.rb +0 -112
  70. data/lib/plezi/handlers/route.rb +0 -216
  71. data/lib/plezi/handlers/session.rb +0 -109
  72. data/lib/plezi/handlers/stubs.rb +0 -156
  73. data/lib/plezi/handlers/ws_identity.rb +0 -253
  74. data/lib/plezi/handlers/ws_object.rb +0 -308
  75. data/lib/plezi/helpers/http_sender.rb +0 -84
  76. data/lib/plezi/helpers/magic_helpers.rb +0 -104
  77. data/lib/plezi/helpers/mime_types.rb +0 -1995
  78. data/lib/plezi/oauth.rb +0 -5
  79. data/lib/plezi/oauth/auth_controller.rb +0 -229
  80. data/logo/dark.png +0 -0
  81. data/logo/light.png +0 -0
  82. data/logo/sign.png +0 -0
  83. data/resources/404.haml +0 -121
  84. data/resources/404.html +0 -124
  85. data/resources/404.slim +0 -120
  86. data/resources/500.haml +0 -120
  87. data/resources/500.slim +0 -120
  88. data/resources/Gemfile +0 -86
  89. data/resources/code.rb +0 -8
  90. data/resources/controller.rb +0 -142
  91. data/resources/database.yml +0 -33
  92. data/resources/db_ac_config.rb +0 -59
  93. data/resources/db_dm_config.rb +0 -51
  94. data/resources/db_sequel_config.rb +0 -33
  95. data/resources/en.yml +0 -204
  96. data/resources/haml_config.rb +0 -6
  97. data/resources/i18n_config.rb +0 -14
  98. data/resources/initialize.rb +0 -49
  99. data/resources/mini_exec.rb +0 -7
  100. data/resources/oauth_config.rb +0 -24
  101. data/resources/plezi_client.js +0 -198
  102. data/resources/plezi_websockets.html +0 -47
  103. data/resources/redis_config.rb +0 -42
  104. data/resources/slim_config.rb +0 -11
  105. data/resources/welcome_page.html +0 -272
  106. data/test/dispatch +0 -58
  107. data/test/hello_world +0 -13
  108. data/test/plezi_tests.rb +0 -581
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ # encoding: UTF-8
3
+
4
+ # set the working directory
5
+ cd "$(dirname "$0")"
6
+ # load the website-app
7
+ bundle exec iodine -t 16 -w 1 -www ./public
File without changes
@@ -0,0 +1,3 @@
1
+ # Edit these parameters if you wish to leverage multi-process concurrency. i.e.:
2
+ # bundle exec iodine -p $PORT -t 16 -w 4 -www ./public -warmup # => 4 processes + fix lazy loading
3
+ web: bundle exec iodine -p $PORT -t 16 -w 1 -www ./public
data/resources/rakefile CHANGED
@@ -1,11 +1,7 @@
1
1
  # load all application code and gems
2
- load ::File.expand_path(File.join("..", "initialize.rb"), __FILE__)
2
+ require 'bundler'
3
+ Bundler.require(:default, ENV['ENV'].to_s.to_sym)
3
4
  # set Plezi to rake mode and load it's tasks (if relevant).
4
- require "plezi/rake"
5
+ Plezi.no_autostart
5
6
 
6
- # create a default task
7
- desc "The default task will simply remind you to call 'rake -T'."
8
- task :default do
9
- puts "I don't know what to do. Please choose a task..."
10
- puts "You can print a list of all avaiulable tasks using: rake -T"
11
- end
7
+ # Add your tasks
data/resources/routes.rb CHANGED
@@ -1,31 +1,14 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
1
+ ################
2
+ # # Place your application routes here.
3
+ # #
4
+ # # Add your routes and controllers by order of priority.
3
5
 
4
- #########
5
- ##
6
- ## This file holds the routes for your application
7
- ##
8
- ## use the `host`, `route` and `shared_route` functions
9
- ##
6
+ # # I18n re-write, i.e.: `/en/home` will be rewriten as `/home`, while setting params['locale'] to "en"
7
+ # Plezi.route "/:locale" , /^(#{I18n.available_locales.join "|"})$/ if defined? I18n
10
8
 
11
-
12
- # This is an optional re-write route for I18n.
13
- # i.e.: `/en/home` will be rewriten as `/home`, while setting params[:locale] to "en"
14
- route "/:locale{#{I18n.available_locales.join "|"}}/*" , false if defined? I18n
15
-
16
- # # This is an optional re-write route response formats.
17
9
  # # Response format re-write, i.e.: `/xml/home` will use .xml templates automatically
18
10
  # # with :locale a request might look like `/en/json/...`
19
- # route "/:format{html|json|xml}/*" , false
20
-
21
- ###
22
- # add your routes here:
23
-
24
-
25
- # remove this demo route and the SampleController once you want to feed Plezi your code.
26
- route '/', SampleController
27
-
11
+ # Plezi.route "/:format" , /^(html|json|xml)$/
28
12
 
29
- # this is a catch all route with a stub controller.
30
- # un comment the following line and replace the controller if you want a catch-all route.
31
- # route '*', Plezi::StubRESTCtrl
13
+ # The root Controller
14
+ Plezi.route '/', RootController
@@ -7,8 +7,8 @@
7
7
 
8
8
  // Your websocket URI should be an absolute path. The following sets the base URI.
9
9
  // remember to update to the specific controller's path to your websocket URI.
10
- var ws_controller_path = window.location.pathname; // change to '/controller/path'
11
- var ws_uri = (window.location.protocol.match(/https/) ? 'wss' : 'ws') + '://' + window.document.location.host + ws_controller_path
10
+ var ws_controller_path = windselfow.location.pathname; // change to '/controller/path'
11
+ var ws_uri = (self.location.protocol.match(/https/) ? 'wss' : 'ws') + '://' + self.document.location.host + ws_controller_path
12
12
  // websocket variable.
13
13
  var websocket = NaN
14
14
  // count failed attempts
@@ -55,4 +55,4 @@ function init_websocket()
55
55
  };
56
56
  }
57
57
  // setup the websocket connection once the page is done loading
58
- window.addEventListener("load", init_websocket, false);
58
+ self.addEventListener("load", init_websocket, false);
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plezi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.22
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boaz Segev
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2016-02-06 00:00:00.000000000 Z
11
+ date: 2016-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: iodine
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.20
19
+ version: 0.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.20
26
+ version: 0.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.7'
33
+ version: '1.12'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.7'
40
+ version: '1.12'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -52,10 +52,23 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '10.0'
55
- description: Plezi - the easy way to add Websockets, RESTful routing and HTTP streaming
56
- services to Ruby Web-Apps.
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ description: The Plezi.io Ruby Framework for real time web applications.
57
70
  email:
58
- - boaz@2be.co.il
71
+ - bo@plezi.io
59
72
  executables:
60
73
  - plezi
61
74
  extensions: []
@@ -68,86 +81,54 @@ files:
68
81
  - LICENSE.txt
69
82
  - README.md
70
83
  - Rakefile
71
- - bin/plezi
72
- - docs/async_helpers.md
73
- - docs/controllers.md
74
- - docs/logging.md
75
- - docs/routes.md
76
- - docs/websockets.md
84
+ - bin/config.ru
85
+ - bin/console
86
+ - bin/hello_world
87
+ - bin/setup
88
+ - exe/plezi
77
89
  - lib/plezi.rb
78
- - lib/plezi/builders/ac_model.rb
79
- - lib/plezi/builders/app_builder.rb
80
- - lib/plezi/builders/builder.rb
81
- - lib/plezi/builders/form_builder.rb
82
- - lib/plezi/common/api.rb
83
- - lib/plezi/common/cache.rb
84
- - lib/plezi/common/defer.rb
85
- - lib/plezi/common/dsl.rb
86
- - lib/plezi/common/redis.rb
87
- - lib/plezi/common/renderer.rb
88
- - lib/plezi/common/settings.rb
89
- - lib/plezi/handlers/controller_core.rb
90
- - lib/plezi/handlers/controller_magic.rb
91
- - lib/plezi/handlers/http_router.rb
92
- - lib/plezi/handlers/placebo.rb
93
- - lib/plezi/handlers/route.rb
94
- - lib/plezi/handlers/session.rb
95
- - lib/plezi/handlers/stubs.rb
96
- - lib/plezi/handlers/ws_identity.rb
97
- - lib/plezi/handlers/ws_object.rb
98
- - lib/plezi/helpers/http_sender.rb
99
- - lib/plezi/helpers/magic_helpers.rb
100
- - lib/plezi/helpers/mime_types.rb
101
- - lib/plezi/oauth.rb
102
- - lib/plezi/oauth/auth_controller.rb
90
+ - lib/plezi/activation.rb
91
+ - lib/plezi/api.rb
92
+ - lib/plezi/controller/controller.rb
93
+ - lib/plezi/controller/controller_class.rb
94
+ - lib/plezi/controller/cookies.rb
95
+ - lib/plezi/helpers.rb
103
96
  - lib/plezi/rake.rb
97
+ - lib/plezi/render/erb.rb
98
+ - lib/plezi/render/has_cache.rb
99
+ - lib/plezi/render/markdown.rb
100
+ - lib/plezi/render/render.rb
101
+ - lib/plezi/render/sass.rb
102
+ - lib/plezi/render/slim.rb
103
+ - lib/plezi/router/adclient.rb
104
+ - lib/plezi/router/assets.rb
105
+ - lib/plezi/router/errors.rb
106
+ - lib/plezi/router/route.rb
107
+ - lib/plezi/router/router.rb
104
108
  - lib/plezi/version.rb
105
- - logo/dark.png
106
- - logo/light.png
107
- - logo/sign.png
109
+ - lib/plezi/websockets/message_dispatch.rb
110
+ - lib/plezi/websockets/redis.rb
108
111
  - plezi.gemspec
109
112
  - resources/404.erb
110
- - resources/404.haml
111
- - resources/404.html
112
- - resources/404.slim
113
113
  - resources/500.erb
114
- - resources/500.haml
115
- - resources/500.html
116
- - resources/500.slim
117
- - resources/Gemfile
118
- - resources/code.rb
114
+ - resources/503.html
115
+ - resources/client.js
119
116
  - resources/config.ru
120
- - resources/controller.rb
121
- - resources/database.yml
122
- - resources/db_ac_config.rb
123
- - resources/db_dm_config.rb
124
- - resources/db_sequel_config.rb
125
- - resources/en.yml
126
- - resources/haml_config.rb
127
- - resources/i18n_config.rb
128
- - resources/initialize.rb
117
+ - resources/ctrlr.rb
118
+ - resources/gemfile
129
119
  - resources/mini_app.rb
130
- - resources/mini_exec.rb
120
+ - resources/mini_exec
131
121
  - resources/mini_welcome_page.html
132
- - resources/oauth_config.rb
133
- - resources/plezi_client.js
134
- - resources/plezi_websockets.html
122
+ - resources/procfile
135
123
  - resources/rakefile
136
- - resources/redis_config.rb
137
124
  - resources/routes.rb
138
- - resources/slim_config.rb
139
- - resources/websockets.js
140
- - resources/welcome_page.html
141
- - test/console
142
- - test/dispatch
143
- - test/hello_world
144
- - test/plezi_tests.rb
145
- homepage: http://www.plezi.io/
125
+ - resources/simple-client.js
126
+ homepage: http://plezi.io
146
127
  licenses:
147
128
  - MIT
148
- metadata: {}
149
- post_install_message: Thank you for installing Plezi, the native Ruby Framework for
150
- real time web-apps.
129
+ metadata:
130
+ allowed_push_host: https://rubygems.org
131
+ post_install_message:
151
132
  rdoc_options: []
152
133
  require_paths:
153
134
  - lib
@@ -166,11 +147,5 @@ rubyforge_project:
166
147
  rubygems_version: 2.5.1
167
148
  signing_key:
168
149
  specification_version: 4
169
- summary: Plezi - the easy way to add Websockets, RESTful routing and HTTP streaming
170
- services to Ruby Web-Apps.
171
- test_files:
172
- - test/console
173
- - test/dispatch
174
- - test/hello_world
175
- - test/plezi_tests.rb
176
- has_rdoc:
150
+ summary: The Plezi.io Ruby Framework for real time web applications.
151
+ test_files: []
data/bin/plezi DELETED
@@ -1,104 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $0="Plezi Builder"
3
- # count lines of code with: ^[ \t]*[\w\d\"\(\{\@\[\]\}\)\:\'\.\*\&]+.*$
4
-
5
- require 'irb'
6
- require 'benchmark'
7
- require 'securerandom'
8
- require 'plezi/builders/builder'
9
- require 'plezi/builders/app_builder'
10
-
11
-
12
-
13
- ######################################################################
14
- # tweek the string class for termial coloring options
15
- class String
16
- # colorization
17
- def colorize(color_code)
18
- "\e[#{color_code}m#{self}\e[0m"
19
- end
20
-
21
- def red
22
- colorize(31)
23
- end
24
-
25
- def green
26
- colorize(32)
27
- end
28
-
29
- def yellow
30
- colorize(33)
31
- end
32
-
33
- def pink
34
- colorize(35)
35
- end
36
- end
37
-
38
- ######################################################################
39
- ######################################################################
40
- ##
41
- ## Start the Build script
42
- ##
43
- ######################################################################
44
- ######################################################################
45
-
46
- # update with http://ruby-doc.org/stdlib-2.2.0/libdoc/optparse/rdoc/OptionParser.html
47
-
48
- # require 'optparser'
49
-
50
- if ARGV[0] == 'new' || ARGV[0] == 'n' || ARGV[0] == "force" || ARGV[0] == 'mini' || ARGV[0] == 'm'
51
- #########
52
- ## set up building environment
53
- ARGV[1] = ARGV[1].gsub /[^a-zA-Z0-9]/, '_'
54
- if Dir.exists?(ARGV[1]) && ARGV[0] != "force"
55
- puts ""
56
- puts "WARNING: app/folder alread exists, use `plezi fource #{ARGV[1]}` to attempt rebuild (no files will be overwritten).".red
57
- puts ""
58
- exit
59
- end
60
- if Dir.exists?(ARGV[1]) && ARGV[0] == "force"
61
- Dir.chdir ARGV[1]
62
- require ::File.expand_path(::Dir["."][0], ( ARGV[1] + ".rb") )
63
- Dir.chdir '..'
64
- end
65
-
66
- # building
67
- template = Plezi::Base::AppBuilder.new
68
- (ARGV[0] == 'mini' || ARGV[0] == 'm' ) ? template.build_mini(ARGV[1]) : template.build(ARGV[1])
69
- elsif ARGV[0] == 'server' || ARGV[0] == 'start' || ARGV[0] == 's'
70
- ARGV.shift
71
- load File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) rescue load( File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last ) ) )
72
- elsif ARGV[0] == 'console' || ARGV[0] == 'c'
73
- load File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) rescue load( File.expand_path(Dir["."][0], (File.expand_path(Dir["."][0]).split(/[\\\/]/).last) ) )
74
- ARGV.clear
75
- Iodine.protocol = nil
76
- IRB.start
77
- else
78
- puts ""
79
- puts "Plezi fast web app starter.".pink
80
- puts "use: plezi new appname"
81
- puts "or: plezi new appname with template-gem-to-put-in another-template-gem-to-put"
82
- puts "==============================".green
83
- puts "new app options:".pink
84
- puts "option description".yellow
85
- puts "new <appname> creates a new application called <appname>."
86
- puts "n alias for new."
87
- puts "mini <appname> creates a new mini-application called <appname>."
88
- puts "m alias for mini."
89
- puts "starting up an app:".pink
90
- puts "start attempts to run the app. accepts any parameters the app supports."
91
- puts "s alias for start/server."
92
- puts "start console innsead of services:".pink
93
- puts "console runs the app. accepts any parameters the app supports."
94
- puts "c alias for start/server."
95
- puts "==============================".green
96
- puts ""
97
- puts "Run the app using the app's script with an optional: -p {port number}. i.e."
98
- puts " cd ./appname".pink
99
- puts " ./appname -p 8080".pink
100
- puts ""
101
- end
102
-
103
-
104
-
@@ -1,245 +0,0 @@
1
- # Plezi's Asynchronous Engine
2
-
3
- (todo: write documentation)
4
-
5
- Inside Plezi's core code is a pure Ruby IO reactor called [Iodine](https://github.com/boazsegev/iodine), a wonderful Asynchronous Workflow Engine that allows us to enjoy both Multi-Threading and Multi-Processing.
6
-
7
- Although multi-threading is highly regarded, it should be pointed out that using the [Iodine](https://github.com/boazsegev/iodine) with just one thread is both faster and more efficient. But, since some tasks that take more time (blocking tasks) can't be broken down into smaller tasks, using a number of threads (and/or processes) is a better practice.
8
-
9
- You can read more about [Iodine](https://github.com/boazsegev/iodine) and it's amazing features in it's [documentation](http://www.rubydoc.info/github/boazsegev/iodine/master).
10
-
11
- Here we will discuss the methods used for asynchronous processing of different tasks that allow us to break big heavy tasks into smaller bits, allowing our application to 'flow' and stay responsive even while under heavy loads.
12
-
13
- ## Asynchronous HTTP responses
14
-
15
- Inside Plezi's core code is a pure Ruby Http and Websocket Server (and client) that comes with [Iodine](https://github.com/boazsegev/iodine) and allows for native Http/1.1 streaming using `chunked` encoding or native Http/2 streaming (built-in to the protocol).
16
-
17
- Asynchronous Http method calls can be nested, but shouldn't be called one after the other.
18
-
19
- i.e.:
20
-
21
- ```ruby
22
- # right
23
- response.stream_async { response.stream_async {'do after'}; 'do first' }
24
- # wrong
25
- response.stream_async { "who's first?" }
26
- response.stream_async { "I don't know..." }
27
- ```
28
-
29
- Since streaming is done asynchronously, and since Plezi is multi-threaded by default (this can be changed to single threaded, but is less recomended unless you know your code doesn't block - see `Plezi::Settings.max_threads = number`), Asynchronous HTTP method nesting makes sure that the code doesn't conflict and that race conditions don't occure within the same HTTP response.
30
-
31
-
32
- #### Iodines's `response.stream_async &block`
33
-
34
- Iodines's response object, which is accessed by the controller using the `response` method (or the `@response` object), allows easy access to HTTP streaming.
35
-
36
- For example (run this in the terminal using `irb`):
37
-
38
- ```ruby
39
- require `plezi`
40
-
41
- class MyController
42
- def index
43
- response.stream_async do
44
- response << "This will stream.\n"
45
- response.stream_async do
46
- response << "Streaming can be nested."
47
- end
48
- end
49
- end
50
- end
51
-
52
- route '/', MyController
53
-
54
- exit
55
- ```
56
-
57
- As noted above, `response.stream_async` calls should always be nested and never called in 'parallel'.
58
-
59
- Calling `response.stream_async`
60
-
61
- #### Iodines's `response.stream_array enum, &block`
62
-
63
- To make nesting easier, Iodines's response object provides the `response.stream_array enum, &block` method.
64
-
65
- Here's our modified example:
66
-
67
- ```ruby
68
- require 'plezi'
69
-
70
- class MyController
71
- def index
72
- data = ["This will stream.\n", "Streaming can be nested."]
73
- response.stream_array(data) {|s| response << s}
74
- end
75
- end
76
-
77
- route '/', MyController
78
-
79
- exit
80
- ```
81
-
82
- You can also add data to the array while 'looping', which allows you to use the array as a 'flag' for looped streaming. The following is a very limited example, which could be used for "lazy loading" data from a database, in order to save on system resources or send large table data using JSON "packets".
83
-
84
- ```ruby
85
- require 'plezi'
86
-
87
- class MyController
88
- def index
89
- data = ["This will stream.\n", "Streaming can be nested."]
90
- flag = [true]
91
- response.stream_array(flag) do
92
- response << data.shift
93
- flag << true unless data.empty?
94
- end
95
- end
96
- end
97
-
98
- route '/', MyController
99
-
100
- exit
101
- ```
102
-
103
- ## Asynchronous code execution
104
-
105
- [Iodine](https://github.com/boazsegev/iodine) has a very powerful Asynchronous Workflow Engine which offers a very intuitve and simplified way to use API both for queuing code snippets (blocks / methods) and for schedualing non-persistent timed events (future timed events are discarded during shutdown and need to be re-initiated).
106
-
107
- ### The Asynchronous "Queue"
108
-
109
- `Iodine`'s core is built with simplicity in mind, making the programmer happy. With this in mind, Iodine offers a single and simple method that allow us to easily queue code execution.
110
-
111
-
112
- #### `Iodine.run(arg1, arg2, arg3...) {block}`
113
-
114
- `Iodine.run` takes arguments to be passed to a block of code prior to execution. This allows us to seperate the `Proc` object creation fron the data handling and possibly (but not always) optimize our code.
115
-
116
- For example:
117
-
118
- ```ruby
119
- require 'plezi'
120
-
121
- class MyController
122
- def index
123
- # Plezi.run automatically defers to Iodine.run
124
- Plezi.run(Time.now) {|t| puts "Someone poked me at: #{t}" } # maybe send an email?
125
- "Hello World"
126
- end
127
- end
128
-
129
-
130
- route '/', MyController
131
-
132
- exit
133
- ```
134
-
135
- This might be optimized like so:
136
-
137
- ```ruby
138
- require 'plezi'
139
-
140
- class MyController
141
- def index
142
- Iodine.run Time.now, &self.class.action_proc
143
- "Hello World"
144
- end
145
-
146
- protected
147
-
148
- def self.action_proc
149
- @proc ||= Proc.new {|t| puts "Someone poked me at: #{t}" } # maybe send an email?
150
- end
151
- end
152
-
153
- route '/', MyController
154
-
155
- exit
156
- ```
157
-
158
- ### Timed events
159
-
160
- Sometimes we want to schedule something to be done in a while, ormaybe we want a task to repeat every certain intevral...
161
-
162
- In come Iodine's TimedEvents: `Iodine.run_after` and `Iodine.run_every`
163
-
164
- #### `Iodine.run_every(seconds, arg1, arg2...) {|arg1, arg2..., timed_event| block }`
165
-
166
- `Iodine.run_every` is very similar to the `Iodine.run`, except it automatically injects an argument to our block, the timed even itself, as the last (optional) parameter. This allows us to stop the repeating event should the need arise.
167
-
168
- ```ruby
169
- require 'plezi'
170
-
171
- class MyController
172
- def index
173
- counter = 0
174
- # Plezi.run_every automatically defers to Iodine.run_every
175
- Plezi.run_every(1, "Counting: %i") do |str, timer|
176
- counter +=1
177
- puts(str % counter)
178
- timer.stop! if counter >= 3
179
- end
180
- "Hello World"
181
- end
182
- end
183
-
184
-
185
- route '/', MyController
186
-
187
- exit
188
- ```
189
-
190
- A similar approach could have been accomplished by setting a repeat limit:
191
-
192
- ```ruby
193
- require 'plezi'
194
-
195
- class MyController
196
- def index
197
- timer = Iodine.run_every(1, "Counting down: %i") do |str, timer|
198
- puts(str % timer.repeat_limit)
199
- end
200
- timer.repeat_limit = 3
201
- "Hello World"
202
- end
203
- end
204
-
205
-
206
- route '/', MyController
207
-
208
- exit
209
- ```
210
-
211
- #### `Iodine.run_after(seconds, arg1, arg2...) {|arg1, arg2..., timed_event| block}`
212
-
213
- `Iodine.run_after` is very similar to the `Iodine.run_every`, except it is designed to "self destruct" after only only execution.
214
-
215
- The timed event allows us to create a new event with the same job, if we wish to.
216
-
217
- ```ruby
218
- require 'plezi'
219
-
220
- class MyController
221
- def index
222
- counter = 0
223
- # Plezi.run_after automatically defers to Iodine.run_after
224
- Iodine.run_after(1, "Counting: %i") do |str, timer|
225
- counter +=1
226
- puts(str % counter)
227
- Iodine.run_after(1, str, &timer.job) if counter < 3
228
- end
229
- "Hello World"
230
- end
231
- end
232
-
233
-
234
- route '/', MyController
235
-
236
- exit
237
- ```
238
-
239
- /// To Do: complete doc.
240
-
241
- ## The Graceful Shutdown
242
-
243
- Enter `Iodine.on_shutdown` - a reverse shutdown task queue (LIFO).
244
-
245
- /// To Do: complete doc.