Capistrano: How to count the number of servers in a role - cluster-computing

I'm creating a deploy.cap which depends on the number of servers there are in the servers.cap to run one task or another, but I can't find/imagine the way to count that array.
This is the servers.cap I have:
server "server1.domain.net", :all, :app
server "server2.domain.net", :all, :app
Could you give me any good example about how to do that? I'm not a capistrano expert, so please the easier, the better.
Many thanks,
Alfredo

You can use the roles DSL to get an array of servers that match a given role. Then you can count the number of items in that array.
For example:
# Capistrano 3.x
puts roles(:all).size
# Capistrano 2.x
puts roles[:all].servers.size

Related

How to create unique ID in format xx-123 on rails

is it possible to create some unique ID for articles on rails?
For example, first article will get ID - aa-001,
second - aa-002
...
article #999 - aa-999,
article #1000 - ab-001 and so on?
Thanks in advance for your help!
The following method gives the next id in the sequence, given the one before:
def next_id(id, limit = 3, seperator = '-')
if id[/[0-9]+\z/] == ?9 * limit
"#{id[/\A[a-z]+/i].next}#{seperator}#{?0 * (limit - 1)}1"
else
id.next
end
end
> next_id("aa-009")
=> "aa-010"
> next_id("aa-999")
=> "ab-001"
The limit parameter specifies the number of digits. You can use as many prefix characters as you want.
Which means you could use it like this in your application:
> Post.last.special_id
=> "bc-999"
next_id(Post.last.special_id)
=> "bd-001"
However, I'm not sure I'd advice you to do it like this. Databases have smart methods to avoid race conditions for creating ids when entries are created concurrently. In Postgres, for example, it doesn't guarantee gapless ids.
This approach has no such mechanism, which could potentially lead to race conditions. However, if this is extremely unlikely to happen such in a case where you are the only one writing articles, you could do it anyway. I'm not exactly sure what you want to use this for, but you might want to look into to_param.
You may want to look into the FriendlyId gem. There’s also a Railscast on this topic which covers a manual approach as well as the usage of FriendlyId.

Best way to convert a Mongo query to a Ruby array?

Let's say I have a large query (for the purposes of this exercise say it returns 1M records) in MongoDB, like:
users = Users.where(:last_name => 'Smith')
If I loop through this result, working with each member, with something like:
users.each do |user|
# Some manipulation to "user"
# Some calculation for "user"
...
# Saving "user"
end
I'll often get a Mongo cursor timeout (as the database cursor that is reserved exceeds the default timeout length). I know I can extend the cursor timeout, or even turn it off--but this isn't always the most efficient method. So, one way I get around this is to change the code to:
users = Users.where(:last_name => 'Smith')
user_array = []
users.each do |u|
user_array << u
end
THEN, I can loop through user_array (since it's a Ruby array), doing manipulations and calculations, without worrying about a MongoDB timeout.
This works fine, but there has to be a better way--does anyone have a suggestion?
If your result set is so large that it causes cursor timeouts, it's not a good idea to load it entirely to RAM.
A common approach is to process records in batches.
Get 1000 users (sorted by _id).
Process them.
Get another batch of 1000 users where _id is greater than _id of last processed user.
Repeat until done.
For a long running task, consider using rails runner.
runner runs Ruby code in the context of Rails non-interactively. For instance:
$ rails runner "Model.long_running_method"
For further details, see:
http://guides.rubyonrails.org/command_line.html

Using the Rally Rest API for CRUD operations

At my company, we recently started using Rally for our project management tool. Initially, someone external to our team invested a lot of time manually creating iterations using a naming convention that is just not going to jive with our team's existing scheme. Instead of asking this poor soul to delete these empty iterations by hand, one by one, I would like to automate this process using Rally's REST API. In short, we need to delete these 100+ empty iterations which span across 3 different projects (which all sharing a common parent).
I have spent some time looking at the rally-rest-api ruby gem, and although I have some limited Ruby experience, the Query interface of the API remains confusing to me, and I am having some trouble wrapping my head around it. I know what my regex would like, but I just don't know how to supply that to the query.
Here is what I have so far:
require 'rubygems'
require 'rally_rest_api'
rally = RallyRestAPI.new(:username => "myuser",
:password => "mypass")
regex = /ET-VT-100/
# get all names that match criteria
iterations = rally.find(:iteration) { "query using above regex?" }
# delete all the matching iterations
iterations.each do |iteration|
iteration.delete
end
Any pointers in the right direction would be much appreciated. I feel like I'm almost there.
I had to do something similar to this a few months back when I wanted to rename a large group of iterations.
First, make sure that the user you are authenticating with has at least "Editor" role assigned in all projects from which you want to delete iterations. Also, if you have any projects in your workspace which you do not have read permissions, you will have to first supply a project(s) element for the query to start from. (You might not even know about them, someone else in your organization could have created them).
The following gets a reference to the projects and then loops through the iterations with the specified regex:
require 'rubygems'
require 'rally_rest_api'
rally = RallyRestAPI.new(:username => "myuser",
:password => "mypass")
# Assumes all projects contain "FooBar" in name
projects = rally.find(:project) { contains :name, "FooBar"}
projects.each do |project|
project.iterations.each do |iteration|
if iteration.name =~ /ET-VT-100/
iteration.delete
end
end
end
Try:
iterations = rally.find(:iteration) { contains :name, "ET-VT-100" }
This assumes that the iteration has ET-VT-100 in the name, you may need to query against some other field. Regexes are not supported by the REST api, afaict.

guid generator in ruby [duplicate]

I have a problem that is really easily solved with GUIDs.
In particular, for a password reset workflow, I would like to send a GUID token to a user's email and have them reset their password using the token. Since GUIDs are unique, this is pretty secure and saves me emailing people passwords, which is risky.
I noticed there is one uuid gem # rubyforge but it looks quite old, and it writes stuff to the file system.
Does anyone know of any other gems that can create a globally unique identifier?
I know I can just fall back to:
(0..16).to_a.map{ |a| rand(16).to_s(16) }.join
But it does not really seem like a proper GUID ...
As of Ruby 1.9, uuid generation is built-in. Use the SecureRandom.uuid function.
For example:
require 'securerandom'
SecureRandom.uuid # => "96b0a57c-d9ae-453f-b56f-3b154eb10cda"
How to create small, unique tokens in Ruby
>> require 'digest'
=> []
>> Digest::SHA1.hexdigest("some-random-string")[8..16]
=> "2ebe5597f"
>> SecureRandom.base64(8).gsub("/","_").gsub(/=+$/,"")
=> "AEWQyovNFo0"
>> rand(36**8).to_s(36)
=> "uur0cj2h"
Did you look at UUIDTools?
UUIDTools was designed to be a simple library for generating any of the various types of UUIDs (or GUIDs if you prefer to call them that). It conforms to RFC 4122 whenever possible.
Google yields the following Ruby library.
Also, over at ruby-forum they say you can install a gem (execute gem uuid on the command line to install it) and then do
gem 'uuid'
puts UUID.new
in your code to see a new UUID.
(Hint: I Googled for guid ruby)
Small update to Simone Carletti answer:
SecureRandom.base64(8).gsub("/","_").gsub(/=+$/,"")
=> "AEWQyovNFo0"
can be replaced with:
SecureRandom.urlsafe_base64(8)
To create a proper, mysql, varchar 32 GUID
SecureRandom.uuid.gsub('-','').upcase
This is a neet technique I learnt from JavaScript:
def uuid
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
"0123456789ABCDEF"[rand(16)]
end
end
Although in a more 'ruby way' one could also do:
def uuid
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
rand(16).to_s(16)
end
end
FOR NEW RAILS VERSIONS >= 5.1
For new Rails versions, you can now use
the methods under Digest::UUID, e.g. Digest::UUID.uuid_v4
See API Docs:
Latest Rails
Rails 5.1
While programming late at night I came up with the following solution (based off Simone's answer) for generating a unique GUID in Rails. I am not proud of it but it does work quite well.
while Order.find_by_guid(guid = rand(36**8).to_s(36).upcase).present?; end
When I used uuid gems recommended in this question, no one can generate unique and random UUID. My answer is a work around, if we have gem later to satisfy the request, you'd better to use gem in Ruby.
I try most recommended uuid gems in this question, but no one make me satisfied, we need unique and random uuid. I directly run system command uuidgen in ruby, and I like the result, and share here.
puts `uuidgen`
8adea17d-b918-43e0-b82f-f81b3029f688
puts `uuidgen`
6a4adcce-8f64-41eb-bd7e-e65ee6d11231
puts `uuidgen`
51d5348b-8fc3-4c44-a6f7-9a8588d7f08a
puts `uuidgen`
332a0fa3-7b07-41e1-9fc8-ef804a377e4e
if compare with uuid gem, you will know the difference.
irb(main):003:0> uuid.generate
=> "40cdf890-ebf5-0132-2250-20c9d088be77"
irb(main):004:0> uuid.generate
=> "4161ac40-ebf5-0132-2250-20c9d088be77"
Test environment is linux and Mac OS environment.
For rails running a postgreSQL database do 2 things.
Step 1: generate a scaffold/model
rails g scaffold manager name:string --primary-key-type=uuid
Step 2: Add a line to migration file
If you rails db:migrate now, you'll get a PG::UndefinedFunction: ERROR: function gen_random_uuid() does not exist error.
So add this to the migration file
enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
Example:
class CreateManagers < ActiveRecord::Migration[7.0]
enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
def change
create_table :managers, id: :uuid do |t|
t.string :name
t.timestamps
end
end
end
You're done!
Oh one last thing, you only nee to add enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto') to one migration file (e.g. the first time you use uuid type).

Generating GUIDs in Ruby

I have a problem that is really easily solved with GUIDs.
In particular, for a password reset workflow, I would like to send a GUID token to a user's email and have them reset their password using the token. Since GUIDs are unique, this is pretty secure and saves me emailing people passwords, which is risky.
I noticed there is one uuid gem # rubyforge but it looks quite old, and it writes stuff to the file system.
Does anyone know of any other gems that can create a globally unique identifier?
I know I can just fall back to:
(0..16).to_a.map{ |a| rand(16).to_s(16) }.join
But it does not really seem like a proper GUID ...
As of Ruby 1.9, uuid generation is built-in. Use the SecureRandom.uuid function.
For example:
require 'securerandom'
SecureRandom.uuid # => "96b0a57c-d9ae-453f-b56f-3b154eb10cda"
How to create small, unique tokens in Ruby
>> require 'digest'
=> []
>> Digest::SHA1.hexdigest("some-random-string")[8..16]
=> "2ebe5597f"
>> SecureRandom.base64(8).gsub("/","_").gsub(/=+$/,"")
=> "AEWQyovNFo0"
>> rand(36**8).to_s(36)
=> "uur0cj2h"
Did you look at UUIDTools?
UUIDTools was designed to be a simple library for generating any of the various types of UUIDs (or GUIDs if you prefer to call them that). It conforms to RFC 4122 whenever possible.
Google yields the following Ruby library.
Also, over at ruby-forum they say you can install a gem (execute gem uuid on the command line to install it) and then do
gem 'uuid'
puts UUID.new
in your code to see a new UUID.
(Hint: I Googled for guid ruby)
Small update to Simone Carletti answer:
SecureRandom.base64(8).gsub("/","_").gsub(/=+$/,"")
=> "AEWQyovNFo0"
can be replaced with:
SecureRandom.urlsafe_base64(8)
To create a proper, mysql, varchar 32 GUID
SecureRandom.uuid.gsub('-','').upcase
This is a neet technique I learnt from JavaScript:
def uuid
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
"0123456789ABCDEF"[rand(16)]
end
end
Although in a more 'ruby way' one could also do:
def uuid
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx".gsub("x") do
rand(16).to_s(16)
end
end
FOR NEW RAILS VERSIONS >= 5.1
For new Rails versions, you can now use
the methods under Digest::UUID, e.g. Digest::UUID.uuid_v4
See API Docs:
Latest Rails
Rails 5.1
While programming late at night I came up with the following solution (based off Simone's answer) for generating a unique GUID in Rails. I am not proud of it but it does work quite well.
while Order.find_by_guid(guid = rand(36**8).to_s(36).upcase).present?; end
When I used uuid gems recommended in this question, no one can generate unique and random UUID. My answer is a work around, if we have gem later to satisfy the request, you'd better to use gem in Ruby.
I try most recommended uuid gems in this question, but no one make me satisfied, we need unique and random uuid. I directly run system command uuidgen in ruby, and I like the result, and share here.
puts `uuidgen`
8adea17d-b918-43e0-b82f-f81b3029f688
puts `uuidgen`
6a4adcce-8f64-41eb-bd7e-e65ee6d11231
puts `uuidgen`
51d5348b-8fc3-4c44-a6f7-9a8588d7f08a
puts `uuidgen`
332a0fa3-7b07-41e1-9fc8-ef804a377e4e
if compare with uuid gem, you will know the difference.
irb(main):003:0> uuid.generate
=> "40cdf890-ebf5-0132-2250-20c9d088be77"
irb(main):004:0> uuid.generate
=> "4161ac40-ebf5-0132-2250-20c9d088be77"
Test environment is linux and Mac OS environment.
For rails running a postgreSQL database do 2 things.
Step 1: generate a scaffold/model
rails g scaffold manager name:string --primary-key-type=uuid
Step 2: Add a line to migration file
If you rails db:migrate now, you'll get a PG::UndefinedFunction: ERROR: function gen_random_uuid() does not exist error.
So add this to the migration file
enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
Example:
class CreateManagers < ActiveRecord::Migration[7.0]
enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto')
def change
create_table :managers, id: :uuid do |t|
t.string :name
t.timestamps
end
end
end
You're done!
Oh one last thing, you only nee to add enable_extension 'pgcrypto' unless extension_enabled?('pgcrypto') to one migration file (e.g. the first time you use uuid type).

Resources