Giter Site home page Giter Site logo

boazsegev / plezi Goto Github PK

View Code? Open in Web Editor NEW
246.0 10.0 9.0 1.85 MB

Plezi - the Ruby framework for realtime web-apps, websockets and RESTful HTTP

Home Page: www.plezi.io

License: MIT License

Ruby 71.99% HTML 17.53% JavaScript 10.19% Shell 0.29%
websockets ruby rack scale framework real-time rest-api

plezi's Introduction

Plezi - a real-time web application framework for Ruby

Gem Version Inline docs GitHub

Note: at this point, plezi.io is mostly a wrapper around the iodine Ruby server. Use iodine directly if possible.

Are microservices on your mind? Do you dream of a an SPA that's easy to scale? Did you wonder if you could write a whole Websockets, RESTful AJAX back-end with just a few lines of code (business logic not included)?

Welcome to your new home with plezi.io, the Ruby real-time framework that assumes the business logic is seperate from the web service logic.

Short and Sweet

What if your next Pub/Sub application could be as easy as:

require 'plezi'
class MyChatroom
  # HTTP
  def index
    render :index
  end
  def on_open
    subscribe channel: :chat
    @name = ::ERB::Util.h(params[:nickname] || "anonymous")
    publish channel: :chat, message: "#{@name} joined the chat."
  end
  def on_message data
    publish channel: :chat, message: "#{@name}: #{::ERB::Util.h data}"
  end
  def on_shutdown
    write "Server is going away. Come back again some other time, #{@name}."
  end
end

Plezi.route '/(:nickname)', MyChatroom

What does Plezi have to offer?

Plezi is a Rack based framework with support for native (server side implemented) Websockets.

Plezi will provide the following features over plain Rack:

  • Object Oriented (M)VC design, BYO (Bring Your Own) models.

  • A case sensitive RESTful router to map HTTP requests to your Controllers.

    Non-RESTful public Controller methods will be automatically published as valid HTTP routes, allowing the Controller to feel like an intuitive "virtual folder" with RESTful features.

  • Raw Websocket connections.

    Websocket connections are now route specific, routing the websocket callbacks to the Controller that "owns" the route.

  • Auto-Dispatch (optional) to automatically map JSON websocket "events" to Controller functions (handlers).

  • Native Pub/Sub provided by Iodine.

  • Automatic (optional) scaling using Redis.

  • An extensible template rendering abstraction engine, supports Slim, Markdown (using RedCarpet) and ERB out of the box.

  • Belated, extensible, asset baking (optional fallback for when the application's assets weren't baked before deployment).

    It's possible to define an asset route (this isn't the default) to bake assets on the fly.

    In production mode, assets will be baked directly to the public folder supplied to Iodine (the web server) with a matching path. This allows the static file server to serve future requests.

    However, during development, baking will save the files to the asset's folder, so that the Ruby layer will be the one serving the content and dynamic updates could be supported.

Things Plezi doesn't do (anymore / ever):

  • No DSL. Plezi won't clutter the global namespace.

  • No application logic inside.

    Conneting your application logic to Plezi is easy, however, application logic should really be independent, reusable and secure. There are plenty of gems that support independent application logic authoring.

  • No native session support. If you must have session support, Rack middleware gems provide a lot of options. Pick one... However...

    Session have been proved over and over to be insecure and resource draining.

    Why use a session when you can save server resources and add security by using a persistent connection, i.e. a Websocket? If you really feel like storing unimportant stuff, why not use javascript's local storage on the client's machine? (if you need to save important stuff, you probably shouldn't be using sessions anyway).

  • No code refresh / development mode. If you want to restart the application automatically whenever you update the code, there are probably plenty of gems that will take care of that.

Do notice, Websockets require Iodine (the server), since (currently) it's the only Ruby server known to support native Websockets using a Websocket Callback Object.

Installation

Add this line to your application's Gemfile:

gem 'plezi'

And then execute:

$ bundle

Or install it yourself as:

$ gem install plezi

Usage

A new application (default applications include a simple chatroom demo):

 $  plezi new app_name

A simple hello world from irb:

require 'plezi'

class HelloWorld
  def index
    "Hello World!"
  end
end

Plezi.route '*', HelloWorld

exit # <= if running from terminal, this will start the server

Documentation

Plezi is fairly well documented.

Documentation is available both in the forms of tutorials and explanations available on the plezi.io website as well as through the YARD documentation.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/boazsegev/plezi.

License

The gem is available as open source under the terms of the MIT License.

plezi's People

Contributors

afaur avatar boazsegev avatar namiwang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

plezi's Issues

Long polling example

Hi,

I would like to use plezi as a long polling HTTP server, which means that I don't want to use it as a fallback from websockets but purely a long polling web server. Are there any example on how to accomplish this?

Also, would it be possible to use these capabilities inside an existing rack/grape ruby app? Migrating from rack would be ok but would need to preserve Grape.

How to skip Plezi (iodine) start server when use rake with Rails?

sorry for my poor English...

plezi/lib/plezi.rb has code like

Iodine.threads = 30
Iodine.run { puts "Plezi is feeling optimistic running version #{::Plezi::VERSION}.\n\n"}

I use the super easy way to load from Rails & add plezi to Rails Gemfile , Rails will auto load Gemfile gems ...... so I can't skip Iodine server start when I use rails rake

rake db:migrate

Iodine server will up and can't skip , even I havn't load any plezi server in Rails

add some code like

if !ENV || !ENV['_'].include?('rake')
  ...#Iodine.run here
end

maybe solve this issue?

Architectural clarification

Hi! I'm not an expert in websockets field and still have a few practical experience with them, only theoretical researches, started some time ago from Faye, Rack bottleneck (partly solved as socket hijacking mechanism) and search for better alternatives that led to invention of Iodine/Plezi. So I just want to clarify some points.

  1. Starting from simple example - chat application, as in your example. You say that Plezi is the wrapper around Iodine web server. How tightly is it coupled to it? If I start app with rackup config.ru -p 9292 - it works. But If I replace Iodine with puma - it does not work:
โ†’ bundle exec puma                 
Puma starting in single mode...
* Version 5.0.2 (ruby 2.7.1-p83), codename: Spoony Bard
* Min threads: 0, max threads: 5
* Environment: development
Running Plezi version: 0.16.4
* Listening on http://0.0.0.0:9292

App is opening, but websockets do not work:

(index):190 WebSocket connection to 'ws://0.0.0.0:9292/' failed: Error during WebSocket handshake: Unexpected response code: 200
init_websocket @ (index):190
(index):203 

So is it possible to interchange Iodine web server with others - puma, falcon? What features have Iodine in comparison with Puma (nio4r) related to sockets?

  1. More practical example. I have an Rails app (on Puma) with separate background (Sneakers/RabbitMQ) workers. Workers change state of models and Frontend should be notified about these changes. I want to replace long polling with Websockets. What architecture should I consider, if I choose Plezi framework?
    First, good choice is to separate Websocket server and HTTP server, which could remain Puma. Second, we need some "Interconnector" block to communicate between my app or background workers to be able to send messages to websocket channel (i.e. that model has been updated). What is this "Interconnector" in case of Plezi? Some redis-baked logic? Do you have some docs of how to construct such solution? We could find drawing of similar architecture from AnyCable docs. How it transforms with use of Plezi/Iodine?

Looking forward for your answer and thanks in advance! )

ERROR -- : could not obtain a database connection within 5.000 seconds (waited 5.000 seconds) (ActiveRecord::ConnectionTimeoutError)

I really appreciate your kind and detailed response to all my reported issue since recently I am trying to utilize Plezi to create some websocket application.

Whenever I refresh the page more than twice, the server crashes and with this error message:

ERROR -- : could not obtain a database connection within 5.000 seconds (waited 5.000 seconds) (ActiveRecord::ConnectionTimeoutError)
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:189:in `block in wait_poll'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:180:in `loop'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:180:in `wait_poll'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:135:in `block in poll'
/Users/davidjuin0519/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:145:in `synchronize'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:133:in `poll'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:425:in `acquire_connection'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:349:in `block in checkout'
/Users/davidjuin0519/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:348:in `checkout'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:263:in `block in connection'
/Users/davidjuin0519/.rvm/rubies/ruby-2.2.3/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:262:in `connection'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:571:in `retrieve_connection'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_handling.rb:113:in `retrieve_connection'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3@global/gems/activerecord-4.2.4/lib/active_record/connection_handling.rb:87:in `connection'

I am sure that the websocket connection is closed and the controller on_close action is triggered...
I wonder what causes the server to crash and how to fix it...

Gap in documentation for serving static assets

When learning Plezi, it's important to know how to serve static assets, in order to try making a primitive usable application example.

Gaps in the documentation make it hard to understand. I'm happy to help improve the documentation, but I need some clues :)

If I can fix this, I think it will help users understand how to take examples in irb and then later understand how they work with Rack, etc.

I'm looking at: http://www.plezi.io/docs/routes

I tried many combinations using the documentation above, but nothing seems to work as described. My main confusion is: In irb, what is a single, simple, complete example of serving a static asset? It might be a JPEG file, CSS file, or JS file that I've already got in my directory.

I can provide more examples of what I've tried, but this is what I assume would work, according to the documentation:

  1. Make this directory/file structure:
    test/
        assets/images/example1.jpg
        public/images/example2.jpg
    
  2. Go into the test directory
  3. Run irb
  4. Paste this code into the IRB, which exits at the end and starts running the Plezi/Iodine server:
    require 'plezi'
    class HelloController
      def index; "Hello, World!"; end
      def show;  "Oh, hello #{params['id']}"; end
    end
    Plezi.route "/hi", HelloController
    exit
  5. Prove that the controller works by going to:
  6. But now, how do I access my example.jpg (from point 1 above)? These paths all give the 404 error:
  7. I also tried modifying the code like this, but it made no difference:
    require 'plezi'
    require 'pathname'; Root = Pathname.new(File.dirname(__FILE__)).expand_path
    Plezi.assets = Root.join('assets').to_s
    class HelloController
      def index; "Hello, World!"; end
      def show;  "Oh, hello #{params['id']}"; end
    end
    Plezi.route "/hi", HelloController
    
    # I also tried adding this, but it didn't help either:
    #Plezi.route '/assets', :assets
    
    exit

I understand that it is perhaps not sensible to run examples in irb that we expect to throw away, while also relying on actual permanent files (for assets). However, as someone learning this it is easier to understand a single app.rb file alongside other asset files, before we make the leap to Rack.

Finding a websocket session and send message

Hi, I was able to find a specific websocket session and send message to the client with following code

Iodine::Websocket.each do |ws|
  if ws.params[:cpid] == cpid
    ws.write "hello"
  end
end

But now something not working as expected. The client keep sending message to server in every 15 seconds but I was not able to find it from the code above. The only change I made to the server related to plezi is changing iodine config from -w 1 to -w 3.
Please help out if there any workaround or better way to find and send message to a specific websocket.

ERROR -- : uninitialized constant OpenSSL::SSL::SSLErrorWaitReadable (NameError)

When I tried to deploy to heroku, the server could not function properly. Here is the error message:

E, [2016-01-31T00:21:56.988242 #3] ERROR -- : uninitialized constant OpenSSL::SSL::SSLErrorWaitReadable (NameError)
2016-01-31T00:21:57.271355+00:00 app[web.1]: /app/vendor/bundle/ruby/2.0.0/gems/iodine-0.1.21/lib/iodine/protocol.rb:115:in `rescue in read'
2016-01-31T00:21:57.271355+00:00 app[web.1]: /app/vendor/bundle/ruby/2.0.0/gems/iodine-0.1.21/lib/iodine/protocol.rb:112:in `read'
2016-01-31T00:21:57.271356+00:00 app[web.1]: /app/vendor/bundle/ruby/2.0.0/gems/iodine-0.1.21/lib/iodine/protocol.rb:186:in `call'
2016-01-31T00:21:57.271357+00:00 app[web.1]: /app/vendor/bundle/ruby/2.0.0/gems/iodine-0.1.21/lib/iodine/core.rb:65:in `work'
2016-01-31T00:21:57.271357+00:00 app[web.1]: /app/vendor/bundle/ruby/2.0.0/gems/iodine-0.1.21/lib/iodine/core.rb:55:in `cycle'
2016-01-31T00:21:57.271358+00:00 app[web.1]: /app/vendor/bundle/ruby/2.0.0/gems/iodine-0.1.21/lib/iodine/core.rb:75:in `block (2 levels) in startup'

I tried to rollback to the workable version, but it crashed as well...
How can I make this work? Thank you!

Upgrade to bundler 2.0

We would like to upgrade our project to bundler 2.0. Can plezi gemspec be changed to not depend on a specific bundler? Right now I am getting an error because plezi depends on ~> 1.14

ERROR -- : incompatible character encodings: ASCII-8BIT and UTF-8 (Encoding::CompatibilityError)

Hi Bo,
When I was trying to render chinese character from db, this error always pops out:

E, [2016-02-04T17:30:09.803387 #3] ERROR -- : incompatible character encodings: ASCII-8BIT and UTF-8 (Encoding::CompatibilityError)
2016-02-04T17:31:51.954972+00:00 app[web.1]: (erb):241:in `concat'
2016-02-04T17:31:51.954972+00:00 app[web.1]: (erb):241:in `render'
2016-02-04T17:31:51.954973+00:00 app[web.1]: /app/vendor/ruby-2.2.3/lib/ruby/2.2.0/erb.rb:863:in `eval'
2016-02-04T17:31:51.954973+00:00 app[web.1]: /app/vendor/ruby-2.2.3/lib/ruby/2.2.0/erb.rb:863:in `result'
2016-02-04T17:31:51.954975+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/common/renderer.rb:119:in `block in <module:Plezi>'
2016-02-04T17:31:51.954975+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/common/renderer.rb:36:in `call'
2016-02-04T17:31:51.954976+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/common/renderer.rb:36:in `block in render'
2016-02-04T17:31:51.954977+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/common/renderer.rb:36:in `each'
2016-02-04T17:31:51.954978+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/common/renderer.rb:36:in `render'
2016-02-04T17:31:51.954978+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/handlers/controller_magic.rb:196:in `render'
2016-02-04T17:31:51.954979+00:00 app[web.1]: /app/config/initializers/websocket.rb:32:in `index'
2016-02-04T17:31:51.954980+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/handlers/controller_core.rb:88:in `_route_path_to_methods_and_set_the_response_'
2016-02-04T17:31:51.954980+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/handlers/route.rb:23:in `on_request'
2016-02-04T17:31:51.954981+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/handlers/http_router.rb:84:in `block in call'
2016-02-04T17:31:51.954982+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/handlers/http_router.rb:84:in `each'
2016-02-04T17:31:51.954982+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/plezi-0.12.21/lib/plezi/handlers/http_router.rb:84:in `call'
2016-02-04T17:31:51.954983+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/iodine-0.1.21/lib/iodine/http/rack_support.rb:19:in `call'
2016-02-04T17:31:51.954983+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/iodine-0.1.21/lib/iodine/http/http1.rb:187:in `dispatch'
2016-02-04T17:31:51.954984+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/iodine-0.1.21/lib/iodine/http/http1.rb:97:in `on_message'
2016-02-04T17:31:51.954985+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/iodine-0.1.21/lib/iodine/protocol.rb:188:in `call'
2016-02-04T17:31:51.954986+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/iodine-0.1.21/lib/iodine/core.rb:65:in `work'
2016-02-04T17:31:51.954986+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/iodine-0.1.21/lib/iodine/core.rb:55:in `cycle'
2016-02-04T17:31:51.954987+00:00 app[web.1]: /app/vendor/bundle/ruby/2.2.0/gems/iodine-0.1.21/lib/iodine/core.rb:75:in `block (2 levels) in startup'

I am pretty sure that the string is encoded in UTF-8...I got no idea why this error occur...
Do you have any idea?

Should add param support to routes?

I'm just thinking out loud if the routes method should support parameters / optional parameters, so we could have something like this:

route '/(:locale{en|de|ru})/book/:id' do
  params[:locale] # => en or de or ru
  params[:id] # => id supplied
end

seems like a nice touch, but should be in the core library or in a different gem (if at all)?

Deploying to heroku

Hi I'm trying to deploy plezi to Heroku and I'm getting stuck here:

remote: -----> Writing config/database.yml to read from DATABASE_URL
remote: 

At first I was using an app that I wrote but I found the issue I tried the sample app from just doing plezi new sample_app

Has any one encountered this before? Is there a workaround for a Heroku deploy?

Here is the whole log

$ git push heroku master 
Counting objects: 38, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (33/33), done.
Writing objects: 100% (38/38), 18.88 KiB | 0 bytes/s, done.
Total 38 (delta 6), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Ruby app detected
remote: -----> Compiling Ruby
remote: -----> Using Ruby version: ruby-2.2.2
remote: -----> Installing dependencies using bundler 1.9.7
remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
remote:        Fetching gem metadata from https://rubygems.org/....
remote:        Fetching version metadata from https://rubygems.org/..
remote:        Using bundler 1.9.7
remote:        Installing iodine 0.1.8
remote:        Installing plezi 0.12.5
remote:        Bundle complete! 1 Gemfile dependency, 3 gems now installed.
remote:        Gems in the groups development and test were not installed.
remote:        Bundled gems are installed into ./vendor/bundle.
remote:        Post-install message from plezi:
remote:        Thank you for installing Plezi, the native Ruby Framework for real time web-apps.
remote:        Bundle completed (1.43s)
remote:        Cleaning up the bundler cache.
remote: -----> Writing config/database.yml to read from DATABASE_URL
remote: 

Documentation help needed.

I'm rewriting Plezi, but rewriting the documentation is far from being my forte... for one, I'm not a native English speaker.

If you want to write a tutorial or add documentation for the Ruby code, please jump in.

You'll need to fork this project for adding YARD documentation using code comments or fork the documentation web application if you're writing any tutorials or help articles.

Help articles and tutorials are written using markdown (the documentation application will convert it all to html, no worries).

Most of the documentation currently references the older (v.0.12.x) API and is dire need of a total rewrite... even simply deleting irrelevant parts will be a help.

Thanks!

server shutdown when one or more client has a poor connection

switching between mobile and wifi network access works fine , however when i went to a specific area ( where the internet is not good ) , i found that server consider that as a slowloris attack and i understand that , but why the server go down if he receive too many "slowloris"

WARNING: (facil.io) possible Slowloris attack from /tmp/facil-io-sock-11935
FATAL: (12073) Parent Process crash detected!
INFO: (12073) detected exit signal.
INFO: (12073) cleanup complete.
WARNING: Child worker (12073) shutdown. Respawning worker.
FATAL: (facil.io) unknown cluster connection error
       errno: No such file or directory
INFO: Server Detected exit signal.

ERROR -- : undefined method `close' for #<Iodine::Http::Response:0x007fad464d6160> (NoMethodError)

This error message keeps showing when I use websocket api to send message....

here is the whole stack:

E, [2016-01-29T13:13:05.480107 #8539] ERROR -- : undefined method `close' for #<Iodine::Http::Response:0x007fad464d6160> (NoMethodError)
/Users/davidjuin0519/Projects/chatty/config/initializers/websocket.rb:27:in `rescue in on_message'
/Users/davidjuin0519/Projects/chatty/config/initializers/websocket.rb:23:in `on_message'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3/gems/plezi-0.12.21/lib/plezi/handlers/ws_object.rb:65:in `on_message'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3/gems/plezi-0.12.21/lib/plezi/handlers/controller_core.rb:54:in `on_message'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3/gems/iodine-0.1.21/lib/iodine/http/websockets.rb:306:in `complete_frame'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3/gems/iodine-0.1.21/lib/iodine/http/websockets.rb:271:in `extract_message'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3/gems/iodine-0.1.21/lib/iodine/http/websockets.rb:15:in `on_message'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3/gems/iodine-0.1.21/lib/iodine/protocol.rb:188:in `call'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3/gems/iodine-0.1.21/lib/iodine/core.rb:65:in `work'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3/gems/iodine-0.1.21/lib/iodine/core.rb:55:in `cycle'
/Users/davidjuin0519/.rvm/gems/ruby-2.2.3/gems/iodine-0.1.21/lib/iodine/core.rb:75:in `block (2 levels) in startup'

here is the code:

def on_message data
  begin
    data = JSON.parse data
  rescue Exception => e
    response << {event: :error, message: "Unknown Error"}.to_json
    response.close
    return false
  end
  broadcast :_send_message, {event: :chat, from: params[:id], message: data["message"], at: Time.now}.to_json
end

How can I solve this problem? Thanks!

Failing at higher concurrency

Hi @boazsegev,

I'm following the-benchmarker/web-frameworks#2288

I'm running on a 4xCPU / 8 G RAM (Linux). The Dockerfile create for plezi is

FROM ruby:2.7-alpine
WORKDIR /usr/src/app
COPY . ./
RUN apk add build-base
RUN bundle config set without 'development test'
RUN bundle install
CMD bundle exec iodine -w $(nproc) -p 3000 -t 1

The command I'm running is
wrk --latency --duration 5s --connections 64 --timeout 8 --threads 8 http://172.17.0.2:3000/

The idea is that is increase concurrency level

  • 64
  • 256
  • 512
  • 1024
  • 2048

When I run manually, everything is OK, but when I run it in an automated ways, it fails (stops) and a concurrency of 256.

Regards,

create function is not synchronized

hello again ...
while trying to send a considerable amount of request via HTTP ( as ws ) to the create function , i figure out that some of data is lost when trying to call the create function many time at the same time ...
i tried to use mutex to handle the problem , but nothing changed
when i start iodine with one worker and one thread nothing is lost .
EDIT
i apologise , about the Mutex resolve the problem by using this :

semaphore = Mutex.new
 semaphore.synchronize {
    # the whole create statement here ....
  }

however i still thinking that iodine need to handle that without using Mutex on my code ...

cannot find resource

tmp $ plezi new conn
/Users/leslie/.rvm/gems/ruby-2.2.0/gems/plezi-0.7.0/bin/plezi:103:in read': No such file or directory @ rb_sysopen - /Users/leslie/.rvm/gems/ruby-2.2.0/gems/plezi-0.7.0/resources/plezi_gray.png (Errno::ENOENT) from /Users/leslie/.rvm/gems/ruby-2.2.0/gems/plezi-0.7.0/bin/plezi:103:ininitialize'
from /Users/leslie/.rvm/gems/ruby-2.2.0/gems/plezi-0.7.0/bin/plezi:255:in new' from /Users/leslie/.rvm/gems/ruby-2.2.0/gems/plezi-0.7.0/bin/plezi:255:in<top (required)>'
from /Users/leslie/.rvm/gems/ruby-2.2.0/bin/plezi:23:in load' from /Users/leslie/.rvm/gems/ruby-2.2.0/bin/plezi:23:in

'
from /Users/leslie/.rvm/gems/ruby-2.2.0/bin/ruby_executable_hooks:15:in eval' from /Users/leslie/.rvm/gems/ruby-2.2.0/bin/ruby_executable_hooks:15:in'

download error with bundled client.js

./config.ru

require 'plezi'
$LOAD_PATH.unshift(File::expand_path('../lib', __FILE__))
require 'app/server'

run ::Plezi.app

./lib/app/server.rb

::Plezi.route('/ws/client.js', :client)
Iodine::Rack.public = File.expand_path('../../public',__dir__)
Iodine::Rack.log = true

./public/index.html

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <link rel="stylesheet" href="/app.css" />
    <script type="text/javascript" src="/ws/client.js"></script>
    <script type="text/javascript" src="/app.js"></script>
  </head>
  <body id="main">
    Welcome!!
  </body>
</html>

lsb_release -a

LSB Version:    :core-4.1-amd64:core-4.1-noarch
Distributor ID: CentOS
Description:    CentOS Linux release 7.4.1708 (Core) 
Release:        7.4.1708
Codename:       Core

Got the same problem on OSX.

ruby -v

tried both

ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]

gem list|grep plezi

plezi (0.15.1)

gem list|grep iodine

iodine (0.4.19)

server side

127.0.0.1 - - [Fri, 19 Apr 2018 14:12:28 GMT] "GET /ws/client.js HTTP/1.1" 200 7700 8ms

firefox

the file status is 200
but the content is empty

wget

--2018-04-20 13:46:34--  (essai: 3)  http://localhost:8080/ws/client.js
Connexion vers localhost (localhost)|127.0.0.1|:8080...connectรฉ.
requรชte HTTP transmise, en attente de la rรฉponse...200 OK
Longueur: 7700 (7,5K)
Sauvegarde en : ยซclient.jsยป

 0% [                                                                                                               ] 0           --.-K/s   ds 0s      

2018-04-20 13:46:34 (0,00 B/s) - Fermeture de la connexion ร  l'octet 0. Nouvel essai.
^C

curl (distribution)

* About to connect() to localhost port 8080 (#0)
*   Trying ::1...
* Connexion refusรฉe
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /ws/client.js HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:8080
> Accept: */*
> 
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< ETag: qTxUfwG6mm0=
< Cache-Control: max-age=3600
< Accept-Ranges: none
< Content-Length: 7700
< Date: Fri, 19 Apr 2018 14:16:30 GMT
< Last-Modified: Fri, 19 Apr 2018 12:48:56 GMT
< Connection: keep-alive
< 
* Problem (2) in the Chunked-Encoded data
* Closing connection 0

curl (last source version)

*   Trying ::1...
* TCP_NODELAY set
* connect to ::1 port 8080 failed: Connexion refusรฉe
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /ws/client.js HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.59.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< ETag: qTxUfwG6mm0=
< Cache-Control: max-age=3600
< Accept-Ranges: none
< Content-Length: 7700
< Date: Fri, 19 Apr 2018 14:49:01 GMT
< Last-Modified: Fri, 19 Apr 2018 12:48:56 GMT
< Connection: keep-alive
< 
* Illegal or missing hexadecimal sequence in chunked-encoding
* Closing connection 0
curl: (56) Illegal or missing hexadecimal sequence in chunked-encoding

From the curl point-of-view https://ec.haxx.se/http-response.html
there should not be Transfer-Encoding: chunked AND Content-Length: 7700 AND there should be chunk size.

Chunked transfer encoding

An HTTP 1.1 server can decide to respond with a "chunked" encoded response,
a feature that wasn't present in HTTP 1.0.

When sending a chunked response, there's no Content-Length: for the response to indicate its size.
Instead, there's a Transfer-Encoding: chunked header that tells curl there's chunked data coming and then in the response body, the data comes in a series of "chunks".
Every individual chunk starts with the size of that particular chunk (in hexadecimal),
then a newline and then the contents of the chunk.
This is repeated over and over until the end of the response, which is signalled with a zero sized chunk.
The point of this sort of response is for the client to be able to figure out when the responses has ended even though the server didn't know the full size before it started to send it.
This is usually the case when the response is dynamic and generated at the point when the request comes.

Clients like curl will, of course, decode the chunks and not show the chunk sizes to users.

JSON event length is limited

When using the included websocket client and auto-dispatch, it appears that the length of a event sent from the browser to plezi is limited.

When the JSON-stringified event is up to 156 bytes, everything works.

Over that length, plezi receives corrupted data when on_message is called and cannot parse it. It then prints "AutoDispatch Warnnig: Received non-JSON message. Closing Connection." on its console. Investigation led to me discover that the JSON.parse(data) call in plezi's controller, in the on_message() method. e.g.

JSON::ParserError: 784: unexpected token at '??{"??en?:"??",??n"??23??th??i??a??st??xt??"u??":??om??ah??:2??59??22?e9??a0??4b??c7??c9??20??0b??8:??ah??la?ge?? g??k ??k ??as??kd??ls??ks?? s??ks??jf??df??sd??kj??df??dl??lf??dl?? X?'

This should have been a JSON string, but it got mangled somewhere in between. It could be iodine or facil.io ?

Help needed!

Hello!
I do not understand how to use sample chat room code you have as an example ((( I started server:

โ†’ ruby chat.rb
Running Plezi version: 0.16.4
Iodine.listen2http is deprecated, use Iodine.listen(service: :http).
WARNING: :app is deprecated in Iodine.listen and Iodine.connect. Use :handler
INFO: Listening on port 3000

but when I'm trying to connect to it via js websockets:

ws = new WebSocket("ws://localhost:3000")

I get an error from server:

ERROR: Iodine caught an unprotected exception - ArgumentError: a target (:to) subject / stream / channel is required.
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/plezi-0.16.4/lib/plezi/controller/controller.rb:162:in `subscribe'
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/plezi-0.16.4/lib/plezi/controller/controller.rb:162:in `subscribe'
chat.rb:8:in `on_open'
/Users/khataev/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/plezi-0.16.4/lib/plezi/controller/bridge.rb:19:in `on_open'

Can't deploy to heroku

I'm pushing a rails app that relies on plezi for websockets to heroku. I was using puma, but removed it

remote:        Removing addressable (2.4.0)
remote: 
remote:  !     Timed out compiling Ruby app (15 minutes)
remote:  !     See https://devcenter.heroku.com/articles/slug-compiler#time-limit
remote: 
remote: Verifying deploy....
remote: 
remote: !   Push rejected to my-app-9999.
remote: 
To https://git.heroku.com/my-app-9999.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/my-app-9999.git'

I followed heroku documentation but it seems to be biased toward big applications, but mine only has 4mb. Has anyone had this problem before?

message_size_limit uninitialized constant Iodine::Http

when i try to put Iodine::Http::Websockets.message_size_limit = 42000 , i got the excpetion : uninitialized constant Iodine::Http
changing the value on the main file to bundle exec iodine -v -maxms 4194304 -t 16 -w 20 -www ./public not changing anything ...
my need is to make socket send message for more than 4 Mb .

Rack < 2.0 : cannot load such file -- rack/query_parser.rb

Trying plezi out for a Rails 4.2 app.
I took out Puma, and Iodine is now supposed to take over as the web server.
Unfortunately rails server returns with the issue:

rails s error:
/home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require': cannot load such file -- rack/query_parser.rb (LoadError)
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `block in require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in `load_dependency'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/plezi-0.14.2/lib/plezi/router/route.rb:4:in `<top (required)>'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `block in require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in `load_dependency'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/plezi-0.14.2/lib/plezi/router/router.rb:1:in `<top (required)>'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `block in require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in `load_dependency'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/plezi-0.14.2/lib/plezi/helpers.rb:2:in `<top (required)>'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `block in require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in `load_dependency'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/plezi-0.14.2/lib/plezi/api.rb:2:in `<top (required)>'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/polyglot-0.3.5/lib/polyglot.rb:65:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `block in require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in `load_dependency'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/plezi-0.14.2/lib/plezi.rb:4:in `<top (required)>'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/bundler-1.16.1/lib/bundler/runtime.rb:81:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/bundler-1.16.1/lib/bundler/runtime.rb:81:in `block (2 levels) in require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/bundler-1.16.1/lib/bundler/runtime.rb:76:in `each'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/bundler-1.16.1/lib/bundler/runtime.rb:76:in `block in require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/bundler-1.16.1/lib/bundler/runtime.rb:65:in `each'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/bundler-1.16.1/lib/bundler/runtime.rb:65:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/bundler-1.16.1/lib/bundler.rb:114:in `require'
        from /home/jericdeleon/Documents/projects/dentca/code/sales-store/backend/config/application.rb:7:in `<top (required)>'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:78:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:78:in `block in server'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:75:in `tap'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:75:in `server'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands.rb:17:in `<top (required)>'
        from /home/jericdeleon/Documents/projects/dentca/code/sales-store/backend/bin/rails:9:in `require'
        from /home/jericdeleon/Documents/projects/dentca/code/sales-store/backend/bin/rails:9:in `<top (required)>'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/spring-2.0.2/lib/spring/client/rails.rb:28:in `load'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/spring-2.0.2/lib/spring/client/rails.rb:28:in `call'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/spring-2.0.2/lib/spring/client/command.rb:7:in `call'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/spring-2.0.2/lib/spring/client.rb:30:in `run'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/spring-2.0.2/bin/spring:49:in `<top (required)>'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/spring-2.0.2/lib/spring/binstub.rb:31:in `load'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/gems/2.3.0/gems/spring-2.0.2/lib/spring/binstub.rb:31:in `<top (required)>'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:68:in `require'
        from /home/jericdeleon/.rbenv/versions/2.3.6/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:68:in `require'
        from /home/jericdeleon/Documents/projects/dentca/code/sales-store/backend/bin/spring:15:in `<top (required)>'
        from bin/rails:3:in `load'
        from bin/rails:3:in `<main>'

Can I ask for any ideas on what to investigate / try next?
This level of error is currently too cryptic for me :(

Here are my gemfiles:

Gemfile
source 'https://rubygems.org'

group :development, :test do
  # use 'dotenv-rails' for development/test environment variables
  gem 'dotenv-rails'
end

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.6'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.1.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc

# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Locking i18n gem version
gem 'i18n', '~> 0.7.0'

# Use Spree
gem 'spree', '3.1.3'
gem 'spree_auth_devise', '3.1.0'
gem 'spree_gateway', '~> 3.3'
gem 'active_model_serializers'

# Use Spree extensions
gem 'spree_mail_settings', github: 'spree-contrib/spree_mail_settings', branch: '3-1-stable'
gem 'spree_editor', github: 'spree-contrib/spree_editor', branch: '3-1-stable'
gem 'spree_print_invoice', github: 'spree-contrib/spree_print_invoice', branch: 'master'

# lock Kaminari to avoid: undefined method num_pages on Spree::Product
# gem 'kaminari', '~> 0.17.0'

# Use AWS for Paperclip's backend
# Paperclip 4 requires aws-sdk < 2; see: https://github.com/thoughtbot/paperclip/wiki/Upgrade-Paperclip-4x-to-5x
gem 'aws-sdk', '< 2.0'

# Use pg as the database for Active Record
gem 'pg', '~> 0.21'

# Use a null database adapter to run rake assets:precompile without database (docker build)
gem "activerecord-nulldb-adapter"  

# Rack Cores
gem 'rack-cors', :require => 'rack/cors'
gem 'rmagick'

# dentca-lab-specific gems
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
# gem 'aws-sdk', '< 2.0'
gem 'seed_dump'

# gem 'sidekiq'
gem 'sucker_punch'

# hunt for n+1 queries
gem 'bullet'

gem 'plezi'

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug'
  gem 'pry'

  # use xray-rails to see template outlines
  gem 'xray-rails'

  # use 'sequel' to retrieve migrate sqlite data to pg
  gem 'sequel'
end

group :development do
  # Access an IRB console on exception pages or by using <%= console %> in views
  gem 'web-console', '~> 2.0'

  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'

  # IDE gems: vscode-ruby
  gem 'ruby-debug-ide'
  gem 'debase'
  gem 'rubocop'
  gem 'solargraph'
  gem 'ripper-tags'
end

group :ist, :uat, :production do
  gem 'rails_12factor'

  # sentry
  gem 'sentry-raven'

  # instrumental
  gem 'instrumental_agent'
end
Gemfile.lock
GIT
  remote: git://github.com/spree-contrib/spree_editor.git
  revision: 702db404e959d6c4fa42fc7c7ea48a28f6bd2d1e
  branch: 3-1-stable
  specs:
    spree_editor (3.1.0)
      ckeditor (~> 4.1.2)
      spree_backend (~> 3.1.0.beta)
      tinymce-rails (~> 4.2.5)

GIT
  remote: git://github.com/spree-contrib/spree_mail_settings.git
  revision: e292a7e843e80ddf0337c68ed4093c702ee60f62
  branch: 3-1-stable
  specs:
    spree_mail_settings (3.1.0)
      spree_backend (~> 3.1.0.beta)

GIT
  remote: git://github.com/spree-contrib/spree_print_invoice.git
  revision: e99527a241bbc6d91ba2f4c3b851c8dc68d70310
  branch: master
  specs:
    spree_print_invoice (3.0.0.beta)
      prawn-rails (~> 0.1.1)
      spree_core (>= 3.1.0, < 4.0)
      spree_extension

GEM
  remote: https://rubygems.org/
  specs:
    actionmailer (4.2.6)
      actionpack (= 4.2.6)
      actionview (= 4.2.6)
      activejob (= 4.2.6)
      mail (~> 2.5, >= 2.5.4)
      rails-dom-testing (~> 1.0, >= 1.0.5)
    actionpack (4.2.6)
      actionview (= 4.2.6)
      activesupport (= 4.2.6)
      rack (~> 1.6)
      rack-test (~> 0.6.2)
      rails-dom-testing (~> 1.0, >= 1.0.5)
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
    actionview (4.2.6)
      activesupport (= 4.2.6)
      builder (~> 3.1)
      erubis (~> 2.7.0)
      rails-dom-testing (~> 1.0, >= 1.0.5)
      rails-html-sanitizer (~> 1.0, >= 1.0.2)
    active_model_serializers (0.10.7)
      actionpack (>= 4.1, < 6)
      activemodel (>= 4.1, < 6)
      case_transform (>= 0.2)
      jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
    activejob (4.2.6)
      activesupport (= 4.2.6)
      globalid (>= 0.3.0)
    activemerchant (1.77.0)
      activesupport (>= 3.2.14, < 6.x)
      builder (>= 2.1.2, < 4.0.0)
      i18n (>= 0.6.9)
      nokogiri (~> 1.4)
    activemodel (4.2.6)
      activesupport (= 4.2.6)
      builder (~> 3.1)
    activerecord (4.2.6)
      activemodel (= 4.2.6)
      activesupport (= 4.2.6)
      arel (~> 6.0)
    activerecord-nulldb-adapter (0.3.8)
      activerecord (>= 2.0.0)
    activesupport (4.2.6)
      i18n (~> 0.7)
      json (~> 1.7, >= 1.7.7)
      minitest (~> 5.1)
      thread_safe (~> 0.3, >= 0.3.4)
      tzinfo (~> 1.1)
    acts_as_list (0.7.2)
      activerecord (>= 3.0)
    addressable (2.5.2)
      public_suffix (>= 2.0.2, < 4.0)
    arel (6.0.4)
    ast (2.4.0)
    autoprefixer-rails (7.2.5)
      execjs
    awesome_nested_set (3.0.3)
      activerecord (>= 4.0.0, < 5)
    aws-sdk (1.67.0)
      aws-sdk-v1 (= 1.67.0)
    aws-sdk-v1 (1.67.0)
      json (~> 1.4)
      nokogiri (~> 1)
    bcrypt (3.1.11)
    binding_of_caller (0.8.0)
      debug_inspector (>= 0.0.1)
    bootstrap-sass (3.3.7)
      autoprefixer-rails (>= 5.2.1)
      sass (>= 3.3.4)
    builder (3.2.3)
    bullet (5.7.6)
      activesupport (>= 3.0.0)
      uniform_notifier (~> 1.11.0)
    byebug (10.0.0)
    camertron-eprun (1.1.1)
    cancancan (1.10.1)
    canonical-rails (0.0.11)
      rails (>= 3.1, < 5.0)
    carmen (1.0.2)
      activesupport (>= 3.0.0)
    case_transform (0.2)
      activesupport
    ckeditor (4.1.6)
      cocaine
      orm_adapter (~> 0.5.0)
    cldr-plurals-runtime-rb (1.0.1)
    climate_control (0.2.0)
    cocaine (0.5.8)
      climate_control (>= 0.0.3, < 1.0)
    coderay (1.1.2)
    coffee-rails (4.1.1)
      coffee-script (>= 2.2.0)
      railties (>= 4.0.0, < 5.1.x)
    coffee-script (2.4.1)
      coffee-script-source
      execjs
    coffee-script-source (1.12.2)
    colorize (0.8.1)
    concurrent-ruby (1.0.5)
    crass (1.0.3)
    css_parser (1.6.0)
      addressable
    debase (0.2.2)
      debase-ruby_core_source (>= 0.10.2)
    debase-ruby_core_source (0.10.2)
    debug_inspector (0.0.3)
    deface (1.0.2)
      colorize (>= 0.5.8)
      nokogiri (~> 1.6.0)
      polyglot
      rails (>= 3.1)
    devise (3.5.10)
      bcrypt (~> 3.0)
      orm_adapter (~> 0.1)
      railties (>= 3.2.6, < 5)
      responders
      thread_safe (~> 0.1)
      warden (~> 1.2.3)
    devise-encryptable (0.1.2)
      devise (>= 2.1.0)
    dotenv (2.2.1)
    dotenv-rails (2.2.1)
      dotenv (= 2.2.1)
      railties (>= 3.2, < 5.2)
    erubis (2.7.0)
    execjs (2.7.0)
    faraday (0.15.3)
      multipart-post (>= 1.2, < 3)
    ffaker (2.2.0)
    ffi (1.9.21)
    font-awesome-rails (4.7.0.3)
      railties (>= 3.2, < 5.2)
    friendly_id (5.1.0)
      activerecord (>= 4.0.0)
    globalid (0.4.1)
      activesupport (>= 4.2.0)
    highline (1.6.21)
    htmlentities (4.3.4)
    i18n (0.7.0)
    instrumental_agent (2.1.0)
      metrician
    iodine (0.7.5)
      rack (>= 1.0, < 3.0)
    jbuilder (2.7.0)
      activesupport (>= 4.2.0)
      multi_json (>= 1.2)
    jquery-rails (4.3.1)
      rails-dom-testing (>= 1, < 3)
      railties (>= 4.2.0)
      thor (>= 0.14, < 2.0)
    jquery-ui-rails (5.0.5)
      railties (>= 3.2.16)
    json (1.8.6)
    jsonapi-renderer (0.2.0)
    kaminari (0.17.0)
      actionpack (>= 3.0.0)
      activesupport (>= 3.0.0)
    libv8 (3.16.14.19)
    loofah (2.1.1)
      crass (~> 1.0.2)
      nokogiri (>= 1.5.9)
    mail (2.7.0)
      mini_mime (>= 0.1.1)
    method_source (0.9.0)
    metrician (0.1.0)
    mime-types (3.1)
      mime-types-data (~> 3.2015)
    mime-types-data (3.2016.0521)
    mimemagic (0.3.0)
    mini_mime (1.0.0)
    mini_portile2 (2.1.0)
    minitest (5.11.3)
    monetize (1.7.0)
      money (~> 6.9)
    money (6.10.1)
      i18n (>= 0.6.4, < 1.0)
    multi_json (1.13.1)
    multipart-post (2.0.0)
    nokogiri (1.6.8.1)
      mini_portile2 (~> 2.1.0)
    orm_adapter (0.5.0)
    paperclip (4.3.7)
      activemodel (>= 3.2.0)
      activesupport (>= 3.2.0)
      cocaine (~> 0.5.5)
      mime-types
      mimemagic (= 0.3.0)
    parallel (1.12.1)
    paranoia (2.1.5)
      activerecord (~> 4.0)
    parser (2.4.0.2)
      ast (~> 2.3)
    pdf-core (0.7.0)
    pg (0.21.0)
    plezi (0.14.2)
      iodine (~> 0.2, >= 0.2.1)
    polyamorous (1.3.3)
      activerecord (>= 3.0)
    polyglot (0.3.5)
    powerpack (0.1.2)
    prawn (2.2.2)
      pdf-core (~> 0.7.0)
      ttfunk (~> 1.5)
    prawn-rails (0.1.1)
      prawn
      prawn-table
      rails (>= 3.1.0)
    prawn-table (0.2.2)
      prawn (>= 1.3.0, < 3.0.0)
    premailer (1.11.1)
      addressable
      css_parser (>= 1.6.0)
      htmlentities (>= 4.0.0)
    premailer-rails (1.10.1)
      actionmailer (>= 3, < 6)
      premailer (~> 1.7, >= 1.7.9)
    pry (0.11.3)
      coderay (~> 1.1.0)
      method_source (~> 0.9.0)
    public_suffix (3.0.1)
    rabl (0.12.0)
      activesupport (>= 2.3.14)
    rack (1.6.8)
    rack-cors (1.0.2)
    rack-protection (1.5.3)
      rack
    rack-test (0.6.3)
      rack (>= 1.0)
    rails (4.2.6)
      actionmailer (= 4.2.6)
      actionpack (= 4.2.6)
      actionview (= 4.2.6)
      activejob (= 4.2.6)
      activemodel (= 4.2.6)
      activerecord (= 4.2.6)
      activesupport (= 4.2.6)
      bundler (>= 1.3.0, < 2.0)
      railties (= 4.2.6)
      sprockets-rails
    rails-deprecated_sanitizer (1.0.3)
      activesupport (>= 4.2.0.alpha)
    rails-dom-testing (1.0.9)
      activesupport (>= 4.2.0, < 5.0)
      nokogiri (~> 1.6)
      rails-deprecated_sanitizer (>= 1.0.1)
    rails-html-sanitizer (1.0.3)
      loofah (~> 2.0)
    rails_12factor (0.0.3)
      rails_serve_static_assets
      rails_stdout_logging
    rails_serve_static_assets (0.0.5)
    rails_stdout_logging (0.0.5)
    railties (4.2.6)
      actionpack (= 4.2.6)
      activesupport (= 4.2.6)
      rake (>= 0.8.7)
      thor (>= 0.18.1, < 2.0)
    rainbow (3.0.0)
    rake (12.3.0)
    ransack (1.4.1)
      actionpack (>= 3.0)
      activerecord (>= 3.0)
      activesupport (>= 3.0)
      i18n
      polyamorous (~> 1.1)
    rb-fsevent (0.10.2)
    rb-inotify (0.9.10)
      ffi (>= 0.5.0, < 2)
    rdoc (4.3.0)
    ref (2.0.0)
    responders (2.4.0)
      actionpack (>= 4.2.0, < 5.3)
      railties (>= 4.2.0, < 5.3)
    ripper-tags (0.6.0)
    rmagick (2.16.0)
    rubocop (0.52.1)
      parallel (~> 1.10)
      parser (>= 2.4.0.2, < 3.0)
      powerpack (~> 0.1)
      rainbow (>= 2.2.2, < 4.0)
      ruby-progressbar (~> 1.7)
      unicode-display_width (~> 1.0, >= 1.0.1)
    ruby-debug-ide (0.6.0)
      rake (>= 0.8.1)
    ruby-progressbar (1.9.0)
    sass (3.5.5)
      sass-listen (~> 4.0.0)
    sass-listen (4.0.0)
      rb-fsevent (~> 0.9, >= 0.9.4)
      rb-inotify (~> 0.9, >= 0.9.7)
    sass-rails (5.0.7)
      railties (>= 4.0.0, < 6)
      sass (~> 3.1)
      sprockets (>= 2.8, < 4.0)
      sprockets-rails (>= 2.0, < 4.0)
      tilt (>= 1.1, < 3)
    sdoc (0.4.2)
      json (~> 1.7, >= 1.7.7)
      rdoc (~> 4.0)
    seed_dump (3.2.4)
      activerecord (>= 4)
      activesupport (>= 4)
    select2-rails (3.5.9.1)
      thor (~> 0.14)
    sentry-raven (2.7.4)
      faraday (>= 0.7.6, < 1.0)
    sequel (5.5.0)
    sinatra (1.4.8)
      rack (~> 1.5)
      rack-protection (~> 1.4)
      tilt (>= 1.3, < 3)
    solargraph (0.10.3)
      parser (~> 2.4)
      sinatra (~> 1.4)
      thor (~> 0.19, >= 0.19.4)
      yard (~> 0.9)
    spree (3.1.3)
      spree_api (= 3.1.3)
      spree_backend (= 3.1.3)
      spree_cmd (= 3.1.3)
      spree_core (= 3.1.3)
      spree_frontend (= 3.1.3)
      spree_sample (= 3.1.3)
    spree_api (3.1.3)
      rabl (~> 0.12.0)
      spree_core (= 3.1.3)
      versioncake (~> 2.3.1)
    spree_auth_devise (3.1.0)
      devise (~> 3.5.4)
      devise-encryptable (= 0.1.2)
      spree_core (~> 3.1.0.beta)
    spree_backend (3.1.3)
      bootstrap-sass (~> 3.3)
      jquery-rails (~> 4.1)
      jquery-ui-rails (~> 5.0)
      select2-rails (= 3.5.9.1)
      spree_api (= 3.1.3)
      spree_core (= 3.1.3)
    spree_cmd (3.1.3)
      thor (~> 0.14)
    spree_core (3.1.3)
      activemerchant (~> 1.59)
      acts_as_list (= 0.7.2)
      awesome_nested_set (~> 3.0.1)
      cancancan (~> 1.10.1)
      carmen (~> 1.0.0)
      deface (~> 1.0.0)
      ffaker (~> 2.2.0)
      font-awesome-rails (~> 4.0)
      friendly_id (~> 5.1.0)
      highline (~> 1.6.18)
      kaminari (~> 0.17)
      monetize (~> 1.1)
      paperclip (~> 4.3.0)
      paranoia (~> 2.1.0)
      premailer-rails
      rails (~> 4.2.5)
      ransack (~> 1.4.1)
      responders
      sprockets-rails
      state_machines-activerecord (~> 0.2)
      stringex
      truncate_html (~> 0.9.3)
      twitter_cldr (~> 3.0)
    spree_extension (0.0.5)
      activerecord (>= 4.2)
    spree_frontend (3.1.3)
      bootstrap-sass (>= 3.3.5.1, < 3.4)
      canonical-rails (~> 0.0.4)
      jquery-rails (~> 4.1)
      spree_api (= 3.1.3)
      spree_core (= 3.1.3)
    spree_gateway (3.3.2)
      spree_core (>= 3.1.0, < 4.0)
      spree_extension
    spree_sample (3.1.3)
      spree_core (= 3.1.3)
    spring (2.0.2)
      activesupport (>= 4.2)
    sprockets (3.7.1)
      concurrent-ruby (~> 1.0)
      rack (> 1, < 3)
    sprockets-rails (3.2.1)
      actionpack (>= 4.0)
      activesupport (>= 4.0)
      sprockets (>= 3.0.0)
    state_machines (0.5.0)
    state_machines-activemodel (0.5.0)
      activemodel (>= 4.1, < 5.2)
      state_machines (>= 0.5.0)
    state_machines-activerecord (0.5.0)
      activerecord (>= 4.1, < 5.2)
      state_machines-activemodel (>= 0.5.0)
    stringex (2.8.2)
    sucker_punch (2.1.1)
      concurrent-ruby (~> 1.0)
    therubyracer (0.12.3)
      libv8 (~> 3.16.14.15)
      ref
    thor (0.20.0)
    thread_safe (0.3.6)
    tilt (2.0.8)
    tinymce-rails (4.2.8)
      railties (>= 3.1.1)
    truncate_html (0.9.3)
    ttfunk (1.5.1)
    turbolinks (5.1.0)
      turbolinks-source (~> 5.1)
    turbolinks-source (5.1.0)
    twitter_cldr (3.6.0)
      camertron-eprun
      cldr-plurals-runtime-rb (~> 1.0)
      tzinfo
    tzinfo (1.2.5)
      thread_safe (~> 0.1)
    uglifier (4.1.5)
      execjs (>= 0.3.0, < 3)
    unicode-display_width (1.4.0)
    uniform_notifier (1.11.0)
    versioncake (2.3.1)
      actionpack (>= 3.2)
      activesupport (>= 3.2)
      railties (>= 3.2)
      tzinfo
    warden (1.2.7)
      rack (>= 1.0)
    web-console (2.3.0)
      activemodel (>= 4.0)
      binding_of_caller (>= 0.7.2)
      railties (>= 4.0)
      sprockets-rails (>= 2.0, < 4.0)
    xray-rails (0.3.1)
      rails (>= 3.1.0)
    yard (0.9.12)

PLATFORMS
  ruby

DEPENDENCIES
  active_model_serializers
  activerecord-nulldb-adapter
  aws-sdk (< 2.0)
  bullet
  byebug
  coffee-rails (~> 4.1.0)
  debase
  dotenv-rails
  i18n (~> 0.7.0)
  instrumental_agent
  jbuilder (~> 2.0)
  jquery-rails
  pg (~> 0.21)
  plezi
  pry
  rack-cors
  rails (= 4.2.6)
  rails_12factor
  ripper-tags
  rmagick
  rubocop
  ruby-debug-ide
  sass-rails (~> 5.0)
  sdoc (~> 0.4.0)
  seed_dump
  sentry-raven
  sequel
  solargraph
  spree (= 3.1.3)
  spree_auth_devise (= 3.1.0)
  spree_editor!
  spree_gateway (~> 3.3)
  spree_mail_settings!
  spree_print_invoice!
  spring
  sucker_punch
  therubyracer
  turbolinks
  tzinfo-data
  uglifier (>= 1.3.0)
  web-console (~> 2.0)
  xray-rails

BUNDLED WITH
   1.16.3

Thank you for your time!

SyntaxError in generated config.ru

plezi new whatever

will generate config.ru with

Iodine::DEFAULT_HTTP_ARGS[:public] = ||= './public'

which leads to

Traceback (most recent call last):
	10: from /Users/nami/.rvm/gems/ruby-2.5.1/bin/ruby_executable_hooks:15:in `<main>'
	 9: from /Users/nami/.rvm/gems/ruby-2.5.1/bin/ruby_executable_hooks:15:in `eval'
	 8: from /Users/nami/.rvm/gems/ruby-2.5.1/bin/iodine:23:in `<main>'
	 7: from /Users/nami/.rvm/gems/ruby-2.5.1/bin/iodine:23:in `load'
	 6: from /Users/nami/.rvm/gems/ruby-2.5.1/gems/iodine-0.6.5/exe/iodine:120:in `<top (required)>'
	 5: from /Users/nami/.rvm/gems/ruby-2.5.1/gems/iodine-0.6.5/exe/iodine:108:in `call'
	 4: from /Users/nami/.rvm/gems/ruby-2.5.1/gems/iodine-0.6.5/exe/iodine:68:in `get_app_opts'
	 3: from /Users/nami/.rvm/gems/ruby-2.5.1/gems/iodine-0.6.5/exe/iodine:51:in `try_file'
	 2: from /Users/nami/.rvm/gems/ruby-2.5.1/gems/rack-2.0.5/lib/rack/builder.rb:40:in `parse_file'
	 1: from /Users/nami/.rvm/gems/ruby-2.5.1/gems/rack-2.0.5/lib/rack/builder.rb:49:in `new_from_string'
/Users/nami/.rvm/gems/ruby-2.5.1/gems/rack-2.0.5/lib/rack/builder.rb:49:in `eval': config.ru:6: syntax error, unexpected tOP_ASGN (SyntaxError)
...EFAULT_HTTP_ARGS[:public] = ||= './public'
...                            ^~~

in ruby-2.5.1

Startup error: undefined method `to_h' for #<Array

I'm following the readme instructions, however Plezi won't startup on my system (SnowLeopard, ruby 1.9.3v551). Here's my gem list & stack trace. Happy to provide more... Thanks.

MacBook:plezi_local_demo wbr$ bundle list
Gems included by the bundle:
  * bundler (1.7.11)
  * greactor (0.1.0)
  * grhttp (0.1.1)
  * plezi (0.11.2)
  * rake (10.4.2)
MacBook:plezi_local_demo wbr$ bundle exec plezi s
/Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/grhttp-0.1.1/lib/grhttp/hpack.rb:212: warning: already initialized constant STATIC_LIST
/Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/grhttp-0.1.1/lib/grhttp/hpack.rb:274: warning: already initialized constant STATIC_LENGTH
/Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/grhttp-0.1.1/lib/grhttp/hpack.rb:277:in `<class:HPACK>': undefined method `to_h' for #<Array:0x00000100b4d6f0> (NoMethodError)
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/grhttp-0.1.1/lib/grhttp/hpack.rb:6:in `<class:HTTP2>'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/grhttp-0.1.1/lib/grhttp/hpack.rb:5:in `<module:Base>'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/grhttp-0.1.1/lib/grhttp/hpack.rb:4:in `<module:GRHttp>'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/grhttp-0.1.1/lib/grhttp/hpack.rb:3:in `<top (required)>'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/grhttp-0.1.1/lib/grhttp.rb:18:in `require'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/grhttp-0.1.1/lib/grhttp.rb:18:in `<top (required)>'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/plezi-0.11.2/lib/plezi.rb:15:in `require'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/plezi-0.11.2/lib/plezi.rb:15:in `<top (required)>'
        from /usr/local/rvm/gems/ruby-1.9.3-p551@global/gems/bundler-1.7.11/lib/bundler/runtime.rb:76:in `require'
        from /usr/local/rvm/gems/ruby-1.9.3-p551@global/gems/bundler-1.7.11/lib/bundler/runtime.rb:76:in `block (2 levels) in require'
        from /usr/local/rvm/gems/ruby-1.9.3-p551@global/gems/bundler-1.7.11/lib/bundler/runtime.rb:72:in `each'
        from /usr/local/rvm/gems/ruby-1.9.3-p551@global/gems/bundler-1.7.11/lib/bundler/runtime.rb:72:in `block in require'
        from /usr/local/rvm/gems/ruby-1.9.3-p551@global/gems/bundler-1.7.11/lib/bundler/runtime.rb:61:in `each'
        from /usr/local/rvm/gems/ruby-1.9.3-p551@global/gems/bundler-1.7.11/lib/bundler/runtime.rb:61:in `require'
        from /usr/local/rvm/gems/ruby-1.9.3-p551@global/gems/bundler-1.7.11/lib/bundler.rb:134:in `require'
        from /Users/wbr/Desktop/plezi_local_demo/environment.rb:21:in `<top (required)>'
        from /Users/wbr/Desktop/plezi_local_demo/plezi_local_demo:5:in `load'
        from /Users/wbr/Desktop/plezi_local_demo/plezi_local_demo:5:in `<top (required)>'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/plezi-0.11.2/bin/plezi:71:in `load'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/plezi-0.11.2/bin/plezi:71:in `rescue in <top (required)>'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/gems/plezi-0.11.2/bin/plezi:71:in `<top (required)>'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/bin/plezi:23:in `load'
        from /Users/wbr/Desktop/plezi_local_demo/vendor/bundle/ruby/1.9.1/bin/plezi:23:in `<main>'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.