Rails: Concurrent requests in development and tests
With puma
you can have concurrent requests. There are two concepts on how Puma can handle two incoming requests: Workers and Threads.
Workers
Puma can have multiple workers. Each worker is a process fork from puma and therefore a very heavy instance and can have multiple threads, that handle the incoming requests.
Example: A Puma server with 2 workers
and 1 thread
each can handle 2 request in parallel
. A third request has to wait until the thread of one of the workers is free.
Threads
Rails is thread-safe since version 4 (n...
Sending TCP keepalives in Ruby
When you make a simple TCP connection to a remote server (like telnet
), your client won't normally notice when the connection is unexpectly severed on the remote side. E.g. if someone would disconnect a network cable from the server you're connected to, no client would notice. It would simply look like nothing is being sent.
You can detect remote connection loss by configuring your client socket to send TCP keepalive signals after some period of inactivity. If those signals are not acknowledged by the other side, your client will terminat...
Geordi 1.0 released
Geordi 1.0 features a command line application geordi
, that holds most of Geordi's previous commands.
New features
-
command help and usage examples right within
geordi
(geordi help
andgeordi help <command>
) -
quick command access: type just the first few letters of a command, e.g.
geordi rs
orgeordi dev[server]
-
command dependencies, e.g.
geordi rspec
invokesgeordi bundle-install
(which bundles only if needed) -
no cluttered
/usr/bin
, but all commands in one handy tool -
template for easily adding new...
Install MySQL 5.6 in Ubuntu 16.04
Instead of using this hack you might want to use MariaDB 10.x which can work with both old and new apps.
An alternative could be to use the MySQL Docker image which is still updated for 5.6.
Ubuntu 16.04 only provides packages for MySQL 5.7 which has a range of backwards compatibility issues with code written against older MySQL versions.
Oracle maintains a list of official APT repositories for MySQL 5.6, but those repositories do...
Debug Ruby code
This is an awesome gadget in your toolbox, even if your test coverage is great.
-
gem install ruby-debug
(Ruby 1.8) orgem install debugger
(Ruby 1.9) - Start your server with
script/server --debugger
- Set a breakpoint by invoking
debugger
anywhere in your code - Open your application in the browser and run the code path that crosses the breakpoint
- Once you reach the breakpoint, the page loading will seem to "hang".
- Switch to the shell you started the server with. That shell will be running an irb session where you can step thr...
Net::SSH::Exception: could not settle on encryption_client algorithm
TL;DR: Update the 'net-ssh' gem by adding to your Gemfile
:
gem 'net-ssh', '=2.9.1'
Now run bundle update net-ssh
. It has no dependencies so it shouldn't update other gems.
If you're using Ruby 1.8.7 and want to update net-ssh to a version > 2.9.1
you also need to add this to your gemfile:
gem 'backports', :require => false
... and in your deploy.rb
add this:
require 'backports/1.9.2/array/select'
Background
You propably have an older version of Capistrano and thereby an older version of `n...
Temporary solution for connection errors with rubygems
The problem
If you're experiencing that your bundle install command fails with an error message like this, rubygems.org might have issues with their ipv6 connectivity:
$ bundle install
Fetching source index from https://rubygems.org/
Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from https://rubygems.org/ due to underlying error <timed out (https://rubygems.org/specs.4.8.gz)>
The (a little bit dirty) possible solution
If that's actually the case, then you can try to deprioritize the ipv...
Bundler: Packaging gems into the git repository (offline installation)
Installing gems on a server that has no access to the internet (especially rubygems.org
) requires to bundle the gems into the repository itself. This requires to adjust the bundle config in the repository.
- Execute the following commands to configure bundler:
bundle config set --local path vendor
bundle config set --local disable_shared_gems true
Note
For Bundler < 2 you have to omit the "set":
bundle config --local name value
.
See here: [https://bundler.io/v1.17/man/bundle-config.1.html](https://bundler.io/v1.17/man...
Working around OpenSSL::SSL::SSLErrors
If your requests blow up in Ruby or CURL, the server you're connecting to might only support requests with older SSL/TLS versions.
You might get an error like: OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=unknown state
SSL Server Test
This SSL Server Test can help finding out which SSL/TLS versions the server can handle.
Ruby
In Ruby, you can teach Net::HTTP
to use a specific SSL/TLS version.
uri = URI.parse(url)
ssl_options = {
use_ssl: true,
ssl_version...
vague puppet error messages with broken yaml files
If you get one of this errors:
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: (<unknown>): found character that cannot start any token while scanning for the next token at line 1297 column 3
Warning: Not using cache on failed catalog
Error: Could not retrieve catalog; skipping run
Error: Could not retrieve catalog from remote server: Error 400 on SERVER: undefined method `empty?' for nil:NilClass at /etc/puppet/environments/production/manifests/nodes.pp:1 on node example.makandra.de
Warning: ...
Apache: Log the original client IP when your site sits behind a reverse proxy
When your site is mapped into the URL-space of another server using mod_proxy
, ProxyPass
and ProxyPassReverse
, all requests in your Apache logs are logged with the IP address of the proxying server. The IP address of the original client doing the request is not logged, making it difficult to trace problems and run statistics.
Short answer
There is no easy way to fix this. Use the log of the proxying server instead, which logs the original client IPs you're looking for.
Long answer
You can fix this for your ac...
Zeus promises to make rails development faster
I am talking about development speed. When your application starts growing and you start adding gems, it starts to take really long to start up, be it the server, console or just running a single spec.
Zeus is smart, you don’t have to put it in your Gemfile or run it with Bundler, all you need to do is create a JSON config file via
zeus init
and then start the serverzeus start
.
After that, you’re ready to go, all you need to do is prefix every command with zeus. That means
rails server
becomeszeus server
, `rails console...
Deliver Paperclip attachments to authorized users only
When Paperclip attachments should only be downloadable for selected users, there are three ways to go.
The same applies to files in Carrierwave.
- Deliver attachments through Rails
The first way is to store Paperclip attachments not in the default public/system
, but in a private path like storage
inside the current release. You should prefer this method when dealing with sensitive data.
Make ...
IMAP: Check credentials
Connect to your IMAP server. If you have SSL enabled:
openssl s_client -connect your-server:993
if your server supports STARTTLS:
openssl s_client -starttls imap -connect your-server:143
otherwise use netcat or telnet (you shouldn't do cleartext stuff nowadays...).
You should see something like this:
...
. OK Pre-login capabilities listed, post-login capabilities have more.
To log into IMAP, send the following string (incl. "01"!):
01 LOGIN user@domani.io $password
The server should return something like:
* C...
Deal with certain travis CI failures
Travis changed their default distribution from Ubuntu 14.04 (trusty) to 16.04 (precise). This might break your test setup for new builds.
You can solve this issue by freezing your test distribution in the .travis.yml
to Ubuntu 14.04 until you have the time to solve all the issues you will have in 16.04:
dist: trusty
Error details
Here are few indicators that you ran into this issue:
Connection to the PostgreSQL database does not work anymore
Your travis-ci builds might have started failing on the usual
psql -c...
jQuery promises: done() and then() are not the same
jQuery's deferred objects behave somewhat like standard promises, but not really.
One of many subtle differences is that there are two ways to chain callbacks to an async functions.
The first one is done
, which only exists in jQuery:
$.ajax('/foo').done(function(html) {
console.debug("The server responded with %s", html);
});
There is also then
, which all promise libraries have:
$.ajax('/foo').then(function(html) {
console.debug("The server resp...
Semantic HTML
Besides their default styling properties, HTML elements have a semantic meaning. For example, an h1
tag is usually styled with a larger font and bold, while it denotes "the single most important headline in its context".
While CSS enables us to style almost any HTML element like anything that is needed, choosing HTML elements corresponding to the meaning of their content has a few advantages:
- HTML becomes a little clearer
- Edge cases have already been considered and implemented:
- Keyboard support (tabbing, arrow keys)
- State...
Never use SET GLOBAL sql_slave_skip_counter with a value higher than 1
If you have a replication error with MySQL and you know the "error" is okay (e.g. you've executed the same statement at the same time on 2 masters which sync each other), you can skip this error and continue with the replication without having to set up the slave from the ground up.
stop slave;
set global sql_slave_skip_counter = 1;
start slave;
But what if you have multiple errors which you want to skip? (e.g. you've executed multiple statement at the same time on 2 masters which sync each other)
Still do not use a value highe...
Resque: Clearance authentication for dashboard
Resque comes with its own dashboard (Resque server) that you can mount inside your Rails 3 application with
#config/routes.rb:
require 'resque/server'
My::Application.routes.draw do
# ...
mount Resque::Server => '/resque'
end
Unfortunately, since this bypasses the filters in your ApplicationController
, everyone can access this dashboard now (unless you have some Rack-based authentication in place, like Devise).
If you're using ...
Make an HTTP request to a machine but fake the hostname
Consider you have a website vhost listening to www.example.com
, redirecting all incoming requests that do not talk about the configured hostname (this is often used to redirect users to http://www.example.com
when entering only http://example.com/
).
If you want to make a request to that site's web server without actually talking to www.example.com
(e.g. because this is a load balancer's address but you want to access one specific machine), you cannot just request machine1.example.com
or localhost
as the above vhost will redirect...
Customize your Bash prompt
The shell variable PS1
holds your bash prompt. You might want to change it to serve your needs best. Here is how to:
General
- non-printing escape sequences in your prompt have to be inclosed in
\[\e[
and\]
so your shell can correctly count its prompt's length - we recommend to highlight your prompt on production machines
- you can also [show different root prompts for each user](https://makandracards.com/makandra/9569-get-the-username-w...
vagrant < 2.2.9: handle conflicting host only adapter
I sometimes had the issue that I received an error when starting an existing vagrant box with vagrant up
:
A host only network interface you're attempting to configure via DHCP
already has a conflicting host only adapter with DHCP enabled. The
DHCP on this adapter is incompatible with the DHCP settings. Two
host only network interfaces are not allowed to overlap, and each
host only network interface can have only one DHCP server. Please
reconfigure your host only network or remove the virtual machine
using the other host only networ...
Exploring the disk usage with ncdu
Ncdu is a disk usage analyzer with an ncurses interface. It is designed to find space hogs on a remote server where you don’t have an entire graphical setup available, but it is a useful tool even on regular desktop systems. Ncdu aims to be fast, simple and easy to use, and should be able to run in any minimal POSIX-like environment with ncurses installed.
Alternatives
du -hs * | sort -h
- Disk Usages Analyser
Terminator: do not broadcast to other windows
Terminator has a cool feature that allows you to split your terminal into many panels and type in all of them at the same time. It's called broadcasting and can be enabled by pressing Alt+a
(and disabled by Alt+o
).
However, in some circumstances it will also be broadcasted to other running instances of Terminator. This probably is not what you want and could be very dangerous (e.g. if you're logged in to a production server in a terminal that is on another workspace).
To prevent the broadcast from affecting other windows, go to `Prefer...