According to the commit comment on 54d84cbb77, AJ/bin/test was intentionally not added,
but AJ tests doesn't actually do anything special other than specifying ENV['AJ_ADAPTER'],
which can be easily done via command line environment variable.
`assert_raise` does not check error message. However, in some tests,
it seems like expecting error message checking with `assert_raise`.
Instead of specifying an error message in `assert_raise`, modify to use
another assert to check the error message.
ActionCable was throwing a "Existing connection must be closed before
opening" exception which was being picked up as a production issue in
our error monitoring software. Since this happens pretty often on any
device that allows the browser to sleep (mobile) this error was getting
triggered often.
This change removes the exception, but keeps logging the occurrence. We
now return `false` to let the caller now that `open` failed.
nio4r 2.0.0 primarily includes new features and bugfixes, with few breaking
changes. The primary reason for bumping the major version is dropping support
for all Ruby versions prior to 2.2.2, so as to match Rails 5.
Full release announcement here:
https://groups.google.com/forum/#!topic/socketry/ZDIUj1ufiJ8
reactor_running? will be true just after the thread enters
EventMachine.run; reactor_thread only gets set after the internal
initialize_event_machine method has been called, the C extension is set
up, and it is entering its run loop.
WebSocket always defers the decision to the server, because it didn't
have to deal with legacy compatibility... but the same-origin policy is
still a reasonable default.
Origin checks do not protect against a directly connecting attacker --
they can lie about their host, but can also lie about their origin.
Origin checks protect against a connection from 3rd-party controlled
script in a context where a victim browser's cookies will be passed
along. And if an attacker has breached that protection, they've already
compromised the HTTP session, so treating the WebSocket connection in
the same way seems reasonable.
In case this logic proves incorrect (or anyone just wants to be more
paranoid), we retain a config option to disable it.
IO#close and IO#read across threads don't get along so well:
After T1 enters #read and releases the GVL, T2 can call #close on the
IO, thereby both closing the fd and freeing the buffer while T1 is using
them.
Before this patch, if you were to make a file edit in your Rails
application and you tried to load up the page, it would hang
indefinitely. The issue is that Active Record is trying to cleanup after
itself and clear all active connection, but Action Cable is still
holding onto a connection from the pool. To resolve this, we are now
shutting down the pubsub adapter before classes are reloaded, to avoid
this altogether (connection is being returned to the pool).
Credits to @skateman for discovering this bug. :)
Mostly, this is just to avoid EventMachine. But there's also an argument
to be made that we're better off using a different protocol library for
our test suite than the one we use to implement the server.
When the `allow_same_origin_as_host` is set to `true`, the request
forgery protection permits `HTTP_ORIGIN` values starting with the
corresponding `proto://` prefix followed by `HTTP_HOST`. This way
it is not required to specify the list of allowed URLs.
Fixes#23757.
Before this commit, even if `reject` was called in the `subscribe`
method for an Action Cable channel, all actions on that channel could
still be invoked. This calls a `return` if a rejected connection tries
to invoke any actions on the channel.
Inserted spaces in the name of Rails components.
Since I was on it, also used PostgreSQL instead of Postgres
because albeit Postgres is an accepted alias, PostgreSQL is
the official name and the actual name of the adapter.
See
https://wiki.postgresql.org/wiki/ProjectName
with regard to PostgreSQL vs Postgres.
- Remove "Configuration", "Running the server", "Dependencies" and "Deployment"
sections from the Action Cable README as they are already duplicated in the
Action Cable overview guide.
Apps that depend on Action Cable don't need Blade for app development,
so we can remove the gem dependency.
We do need Blade for Action Cable dev, so we bundle it in the Gemfile.
Signed-off-by: Jeremy Daer <jeremydaer@gmail.com>
- Now we will detect what javascript engine user is using and based on
that we will generate either `.js` or `.coffee` version of the channel
file.
- This also needs a change in coffee-rails to override the `js_template`
method. Related PR https://github.com/rails/coffee-rails/pull/72.
- Currently coffee-rails gem sets
`config.app_generators.javascript_engine` to `:coffee` and using this
information we override the `js_template` to set the extension as
`.coffee` in coffee-rails gem.
- Using this approach, we can keep the `channel.js` and `channel.coffee`
files in the Rails repository itself.
- Additionally the `js_template` method can act as public interface for
coffee-rails gem to hook into and change the extension to `.coffee`
without maintaining the actual asset files.
[Prathamesh Sonpatki, Matthew Draper]
This is an engine living in action_cable/engine.rb, convention is to
call these things *::Engine.
Looking at thi git history looks like the current *::Railtie was just
an accident.
* Use separate stream handler builders for easy override and testing.
* Fix worker pool execution that was silently failing since it only
expected connection receivers.
Sparked by code in #24162.
* Rewrite docs
* Support blocks in addition to method names and Proc args
* Check for valid arguments
* Convert `periodically :method_name` to Proc callbacks
* Drop periodic runner methods from the worker pool
* Ensure we clear active periodic timers after shutdown
Alternate implementation of #24162 with tests. The code had diverged
too far on master to pull that implemenation directly.
Fixes#23778Close#24162
[Mattew Draper & Sean Griffin]
This is primarily for backwards compatibility for when
or if the protocol is changed in future versions.
If the server fails to respond with an acceptable
protocol, the client disconnects and disables
the monitor.
* Introduce a connection coder responsible for encoding Cable messages
as WebSocket messages, defaulting to `ActiveSupport::JSON` and duck-
typing to any object responding to `#encode` and `#decode`.
* Consolidate encoding responsibility to the connection. No longer
explicitly JSON-encode from channels or other sources. Pass Cable
messages as Hashes to `#transmit` and rely on it to encode.
* Introduce stream encoders responsible for decoding pubsub messages.
Preserve the currently raw encoding, but make it easy to use JSON.
Same duck type as the connection encoder.
* Revert recent data normalization/quoting (#23649) which treated
`identifier` and `data` values as nested JSON objects rather than as
opaque JSON-encoded strings. That dealt us an awkward hand where we'd
decode JSON strings… or not, but always encode as JSON. Embedding
JSON object values directly is preferably, no extra JSON encoding,
but that should be a purposeful protocol version change rather than
ambiguously, inadvertently supporting multiple message formats.
Whack it down from 100 to 4.
Large worker pools means large db connection counts. We aren't set up
for that by default and most apps won't need it out of the box.
We're better off tuning the default worker pool for low traffic, low
resource consumption apps. Those who have higher traffic will scale up
to meet demand.
To move Action Cable logging to a LoggingSubscriber we need to pass the
log tags in the notification payload since Action Cable logging use the
Channel instance to tag the logs.
`skip` raises an exception to abort the execution of the test, so
`super` would never be called and thus `@rx_adapter` and `@tx_adapter`
would never have been defined at the time of teardown.
Define them just before skipping and zap the warnings.
EM::Hiredis were spewing screenfuls of warnings when running the Action Cable tests.
Copied over the technique that shushes up faye-websocket in the client tests, so
we can reduce the noise ratio.
Note: there's still warnings spewed after tests have finished when EM::Hiredis shuts
down. I haven't been able to shush them up yet.
We'll get `Errno::ECONNRESET` if the client forcibly disconnected.
Just close the socket rather than raising the exception.
Handle other errors in `ClientSocket#write`, too, mirroring the Faye
error handling which swallows all `StandardError` on write.
* More intention revealing than connecting on the first call to Connection#send
* Fixes that calls to Connection#send would attempt to open a connection when the WebSocket's state is CONNECTING
This change makes ping into a message type, which
makes the whole protocol a lot more consistent.
Also fixes hacks on the client side to make this all
work.
Similar to the channel streaming side, these values must be strings for
ActionCable to behave as expected. The conversion will allow users to
send string-convertible values and get the expected behavior.
ActionCable does some things behind the scenes that expects these
"broadcasting"s or "channel"s to be strings. However it's not
immediately obvious that the value must be a string. So adding this
conversion ensures things work as expected.
We are seeing cases where the websockets get stuck in the 'closing' state
after a tab has been in background for a while. So lets treat those websockets
as closed.
Before this commit, the `unsubscribed` callbacks in Action Cable server
side channels were never called. This is because when a WebSocket
"goodbye" message was sent from the client, the Action Cable server
didn't properly clean up after the now closed WebSocket. This means that
memory could possibly skyrocket with this behavior, since part of this
commit is to properly remove closed subscriptions from the global
subscriptions hash. Say you have 10,000 users currently connected, and
then all 10,000 disconnect -- before this patch, Action Cable would
still hold onto information (and Ruby objects!) for all of these now
dead connections.
When running the ActionCable server in development I get a lot of output
in my logs, this commit sets a maximum length of 300 characters for a
broadcast log message.
This PR checks all active Action Cable documentation for typos and other
fixes. It aims to make sure that when Rails 5 is released, that the
Action Cable docs are up to snuff with the other documentation included
with Rails.
[ci skip]
The `WorkerTest`'s `Receiver` is imporsonating an `ActionCable::Connection::Base`, but
just delegates the logger to `ActionCable.logger`.
This creates a mismatch as the connection requires the logger to be a
`TaggedLoggerProxy`'ied logger, while the server doesn't.
Thus to ensure an exception isn't raised when the worker tries to call `tag`
other tests have to assign a proxied logger to their test server.
Instead of forcing change on other tests, have Receiver adhere to the connection
contract and use a `TaggedLoggerProxy`.
As a consequence remove more setup from the tests.
Instead of depending on ApplicationCable::Connection being defined at initialize
we should inject it in the Railtie.
Thus we can kill more setup in the tests too.
We were explicitly referencing Rails.root in ActionCable::Server::Configuration.initialize,
thereby coupling ourselves to Rails.
Instead add `app/channels` to Rails' app paths and assign the existent files
to `channel_paths`.
Users can still append to those load paths with `<<` and `push` in `config/application.rb`.
This means we can remove the custom `Dir` lookup in `channel_paths` and the Rails
and root definitions in the tests.
Some existing examples used ActionCable.server.config but for
configuring allowed_request_origins that is overridden in development
mode. The correct place to set that is
Rails.application.config.action_cable which the ActionCable initializer
loads from. I thought the other two examples should be changed as well
just in case a default value that would override a configured value is
introduced for either log_tags or disable_request_forgery_protection in
the future.
* Properly indent code sample in ActionCable::Channel::Streams
* Add a doc comment for #stop_all_streams
* Reformat + add <tt> blocks around code references in ActionCable::Base docs
* Clarify and a little better grammar on ActionCable::RemoteConnections
* Correct indentation and clean up ActionCable::Server::Broadcasting code sample
This new adapter does get a little more intimate with the redis-rb gem's
implementation than I would like, but it's the least bad of the
approaches I've come up with.