Skip to content

Commit 3618578

Browse files
authored
Merge branch 'master' into patch-1
2 parents db3a171 + 0ffbb46 commit 3618578

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+3647
-1164
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ tmp
1212
.env
1313
NOTES.md
1414
.envrc
15+
/db/

.travis.yml

+11-13
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
1+
language: ruby
12
dist: trusty
2-
sudo: false
3-
dist: trusty
4-
53
rvm: 2.4.2
64

7-
cache: bundler
5+
cache:
6+
bundler: true
87

98
services:
10-
- redis
11-
- rabbitmq
9+
- redis
10+
- rabbitmq
1211

1312
addons:
14-
postgresql: 9.3
13+
postgresql: 9.6
1514

1615
env:
1716
matrix:
1817
- RAKE_TASK=spec
1918
global:
2019
secure: BdVC3OHqYcgePLrkKIk28Ewn/dxCYFf3Cx+Q8P+BCDj6UPJyRSbKmILBzuX96H5xhKmUFo0A/upUhJI9UUP9aXHO7MzRe04/c88QdO4wGacVUaIyB20S0pr262zbc/nA50K9cVgpmWc64n6uQR1tgM6ZyyBnBeXkLzCAOHPq99I=
2120

22-
before_install:
23-
- gem install bundler
24-
before_script:
25-
- bundle exec rake db:create --trace
26-
script:
27-
- bundle exec rspec spec
21+
before_install: gem install bundler
22+
23+
before_script: bundle exec rake db:create --trace
24+
25+
script: bundle exec rspec spec

Gemfile

+7-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ruby '2.4.2' if ENV['DYNO']
55
gem 'travis-config', '~> 1.1.3'
66
gem 'travis-lock'
77
gem 'travis-metrics', git: 'https://github.com/travis-ci/travis-metrics'
8-
gem 'travis-rollout', git: 'https://github.com/travis-ci/travis-rollout', ref: 'sf-refactor'
8+
gem 'travis-rollout', git: 'https://github.com/travis-ci/travis-rollout'
99
gem 'travis-exceptions', git: 'https://github.com/travis-ci/travis-exceptions'
1010
gem 'travis-logger', git: 'https://github.com/travis-ci/travis-logger'
1111
gem 'travis-settings', git: 'https://github.com/travis-ci/travis-settings'
@@ -22,7 +22,7 @@ gem 'sidekiq-pro', require: 'sidekiq-pro', source: 'https://gems.contribsys.com'
2222
gem 'jemalloc'
2323
gem 'redis-namespace'
2424
gem 'activerecord', '~> 4.2.7'
25-
gem 'bunny', '~> 2.6.1'
25+
gem 'bunny', '~> 2.9.2'
2626
gem 'pg'
2727
gem 'concurrent-ruby'
2828
gem 'sentry-raven'
@@ -33,9 +33,13 @@ gem 'rack', '1.6.4'
3333

3434
gem 'libhoney'
3535

36+
group :development, :test do
37+
gem 'pry'
38+
end
39+
3640
group :test do
3741
gem 'rake'
38-
gem 'database_cleaner', '~> 1.5.1'
42+
gem 'database_cleaner', '~> 1.7'
3943
gem 'factory_girl', '~> 4.7.0'
4044
gem 'mocha', '~> 0.10.0'
4145
gem 'rspec'

Gemfile.lock

+26-21
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ GIT
6262

6363
GIT
6464
remote: https://github.com/travis-ci/travis-rollout
65-
revision: 643477fb44ea35d483ed24cc89ced459719c6e6c
66-
ref: sf-refactor
65+
revision: ac0184411b3618dd5e5706db8fe7676a107c7b07
6766
specs:
6867
travis-rollout (0.0.1)
6968

@@ -94,7 +93,7 @@ GEM
9493
tzinfo (~> 1.1)
9594
addressable (2.5.1)
9695
public_suffix (~> 2.0, >= 2.0.2)
97-
amq-protocol (2.0.1)
96+
amq-protocol (2.3.0)
9897
arel (6.0.4)
9998
atomic (1.1.99)
10099
avl_tree (1.2.1)
@@ -105,19 +104,20 @@ GEM
105104
thread_safe (~> 0.3, >= 0.3.1)
106105
backports (3.10.3)
107106
builder (3.2.3)
108-
bunny (2.6.1)
109-
amq-protocol (>= 2.0.1)
107+
bunny (2.9.2)
108+
amq-protocol (~> 2.3.0)
110109
cl (0.0.4)
110+
coderay (1.1.2)
111111
coercible (1.0.0)
112112
descendants_tracker (~> 0.0.1)
113113
concurrent-ruby (1.0.5)
114114
connection_pool (2.2.1)
115115
crack (0.4.3)
116116
safe_yaml (~> 1.0.0)
117-
database_cleaner (1.5.3)
117+
database_cleaner (1.7.0)
118118
descendants_tracker (0.0.4)
119119
thread_safe (~> 0.3, >= 0.3.1)
120-
diff-lcs (1.2.5)
120+
diff-lcs (1.3)
121121
domain_name (0.5.20170404)
122122
unf (>= 0.0.5, < 1.0.0)
123123
equalizer (0.0.11)
@@ -144,6 +144,7 @@ GEM
144144
libhoney (1.3.2)
145145
http (~> 2.0)
146146
metaclass (0.0.4)
147+
method_source (0.9.0)
147148
minitest (5.11.3)
148149
mocha (0.10.5)
149150
metaclass (~> 0.0.1)
@@ -152,9 +153,12 @@ GEM
152153
net-http-persistent (2.9.4)
153154
net-http-pipeline (1.0.1)
154155
pg (0.21.0)
156+
pry (0.11.3)
157+
coderay (~> 1.1.0)
158+
method_source (~> 0.9.0)
155159
public_suffix (2.0.5)
156160
rack (1.6.4)
157-
rack-protection (1.5.3)
161+
rack-protection (2.0.1)
158162
rack
159163
rake (11.3.0)
160164
redis (3.3.3)
@@ -163,19 +167,19 @@ GEM
163167
redlock (0.1.8)
164168
redis (~> 3, >= 3.0.0)
165169
rollout (1.1.0)
166-
rspec (3.5.0)
167-
rspec-core (~> 3.5.0)
168-
rspec-expectations (~> 3.5.0)
169-
rspec-mocks (~> 3.5.0)
170-
rspec-core (3.5.4)
171-
rspec-support (~> 3.5.0)
172-
rspec-expectations (3.5.0)
170+
rspec (3.7.0)
171+
rspec-core (~> 3.7.0)
172+
rspec-expectations (~> 3.7.0)
173+
rspec-mocks (~> 3.7.0)
174+
rspec-core (3.7.1)
175+
rspec-support (~> 3.7.0)
176+
rspec-expectations (3.7.0)
173177
diff-lcs (>= 1.2.0, < 2.0)
174-
rspec-support (~> 3.5.0)
175-
rspec-mocks (3.5.0)
178+
rspec-support (~> 3.7.0)
179+
rspec-mocks (3.7.0)
176180
diff-lcs (>= 1.2.0, < 2.0)
177-
rspec-support (~> 3.5.0)
178-
rspec-support (3.5.0)
181+
rspec-support (~> 3.7.0)
182+
rspec-support (3.7.1)
179183
safe_yaml (1.0.4)
180184
sentry-raven (2.6.3)
181185
faraday (>= 0.7.6, < 1.0)
@@ -210,11 +214,11 @@ PLATFORMS
210214

211215
DEPENDENCIES
212216
activerecord (~> 4.2.7)
213-
bunny (~> 2.6.1)
217+
bunny (~> 2.9.2)
214218
cl
215219
coder!
216220
concurrent-ruby
217-
database_cleaner (~> 1.5.1)
221+
database_cleaner (~> 1.7)
218222
factory_girl (~> 4.7.0)
219223
gh!
220224
jemalloc
@@ -225,6 +229,7 @@ DEPENDENCIES
225229
mocha (~> 0.10.0)
226230
multi_json (~> 1.11)
227231
pg
232+
pry
228233
rack (= 1.6.4)
229234
rake
230235
redis-namespace

Procfile

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
console: bundle exec je ./bin/console
2-
sidekiq: bundle exec je bin/sidekiq ${SIDEKIQ_CONCURRENCY:-5} ${SIDEKIQ_QUEUE:-scheduler}
3-
scheduler: bundle exec je bin/sidekiq ${SIDEKIQ_CONCURRENCY:-5} ${SIDEKIQ_QUEUE:-scheduler}
2+
sidekiq: bundle exec je bin/sidekiq-pgbouncer ${SIDEKIQ_CONCURRENCY:-5} ${SIDEKIQ_QUEUE:-scheduler}
3+
scheduler: bundle exec je bin/sidekiq-pgbouncer ${SIDEKIQ_CONCURRENCY:-5} ${SIDEKIQ_QUEUE:-scheduler}

README.md

+16-20
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,26 @@ only queue 2 more jobs in order to respect the limit of 5.
2929
The log output for each of these evaluation rounds looks like this:
3030

3131
```
32-
one-org: total: 5, running: 8, max: 20, queueable: 5
33-
another-org: total: 20, running: 2, max: 2, queueable: 0
32+
user sven public capacity: total=3 running=1 selected=2
33+
user sven boost capacity: total=2 running=0 selected=2
34+
repo sven/repo: queueable=5 running=1 selected=4 waiting=1
35+
user sven: queueable=5 running=1 selected=4 total_waiting=1 waiting_for_concurrency=1
3436
```
3537

3638
The terminology used here can be confusing. The terms mean:
3739

38-
* `total` is the number of jobs waiting in the `created` state
39-
* `running` is the number of jobs already running, so the number of jobs that
40-
have state `queued`, `received`, or `started`
41-
* `max` is the concurrency limit for the given owner, i.e. the maximum number
42-
of jobs
43-
* `queueable` is the result of the evaluation: how many jobs can be queued up,
44-
i.e. "sent to the workers", at this moment
45-
46-
In the example log output above, on the first line the owner `one-org` has a
47-
concurrency limit of 20. It has 5 jobs waiting to be queued ("total"), and
48-
already has 8 jobs running at this moment. Therefore the scheduler can queue up
49-
5 more jobs for the workers to pick them up and execute them. (And, if someone
50-
on this org would have pushed 12 more jobs in this moment, it could queue up
51-
all 12 of them, too.)
52-
53-
On the second line the owner `another-org` has a concurrency limit of 2, 20
54-
jobs waiting ("total"), and 2 already running. Therefore the scheduler can not
55-
queue up any more jobs (`queueable: 0`) at this moment.
40+
* `total` - number of concurrent jobs, provided by public capacity, plan, boost, etc.
41+
* `running` - number of jobs currently running, i.e. in the state `queued`, `received`, or `started`
42+
* `queueable` - number of jobs in the state `created`
43+
* `selected` - number of queueable jobs that are being selected to be queued based on concurrency limits
44+
* `total_waiting` - total number of queueable jobs that have not been selected to be queued
45+
* `waiting_for_concurrency` - number of queueable jobs that have not been selected, and have not been found to be limited by repo settings, queue, or stages
46+
47+
In the example log output above, the owner has a capacity of 3 concurrent jobs
48+
provided by `public` capacity (line 1), and 2 jobs provided by `boost` capacity
49+
(line 2). The job selection finds 5 jobs to be queueable (i.e. in the state
50+
`created`), and 1 job to be running. As the total capacity is 5 jobs it can
51+
select 4 jobs to be queued for the workers, leaving 1 job waiting.
5652

5753
## Contributing
5854

TODO.md

-9
This file was deleted.

bin/sidekiq-pgbouncer

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bash
2+
# this script enables a pgbouncer wrapper when the
3+
# $PGBOUNCER_ENABLED variable is set to 'true'
4+
# or if the space-delimited list
5+
# $PGBOUNCER_ENABLED_FOR_DYNOS contains $DYNO
6+
7+
cd "$(dirname "$0")/.."
8+
9+
for d in $PGBOUNCER_ENABLED_FOR_DYNOS; do
10+
if [ "$d" = "$DYNO" ]; then
11+
export PGBOUNCER_ENABLED=true
12+
fi
13+
done
14+
15+
if [ ! -f "bin/start-pgbouncer-stunnel" ]; then
16+
echo "warning: pgbouncer buildpack not found, setting PGBOUNCER_ENABLED=false"
17+
export PGBOUNCER_ENABLED=false
18+
fi
19+
20+
if [ "$PGBOUNCER_ENABLED" = 'true' ]; then
21+
export PGBOUNCER_PREPARED_STATEMENTS=false
22+
exec bin/start-pgbouncer-stunnel bin/sidekiq "$@"
23+
else
24+
exec bin/sidekiq "$@"
25+
fi

lib/travis/owners.rb

+5-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@
77

88
module Travis
99
module Owners
10+
ArgumentError = Class.new(::ArgumentError)
11+
1012
class << self
11-
def group(owner, config)
13+
def group(owner, config, logger = nil)
1214
owner = find(owner) if owner.is_a?(Hash)
13-
Group.new(owners(owner, config), config)
15+
Group.new(owners(owner, config), config, logger)
1416
end
1517

1618
def find(owner)
19+
raise ArgumentError, 'Invalid owner data: %p' % owner unless owner[:owner_type]
1720
Kernel.const_get(owner[:owner_type]).find(owner[:owner_id])
1821
end
1922

lib/travis/owners/config.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def login
2727
end
2828

2929
def delegate
30-
config[login.to_sym]
30+
config[login.try(:to_sym)]
3131
end
3232

3333
def delegatees(*logins)

lib/travis/owners/group.rb

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module Travis
22
module Owners
3-
class Group < Struct.new(:all, :config)
3+
class Group < Struct.new(:all, :config, :logger)
44
include Enumerable
55

66
def each(&block)
@@ -12,12 +12,13 @@ def key
1212
end
1313

1414
def logins
15-
@login ||= all.map(&:login).sort
15+
@logins ||= all.map(&:login).compact.sort
1616
end
1717

18-
def max_jobs
19-
subscriptions.max_jobs
18+
def paid_capacity
19+
subscriptions.capacity
2020
end
21+
alias max_jobs paid_capacity
2122

2223
def subscribed?
2324
subscriptions.active?
@@ -27,6 +28,10 @@ def subscribed_owners
2728
subscriptions.subscribers
2829
end
2930

31+
def educational?
32+
all.any?(&:educational?)
33+
end
34+
3035
def ==(other)
3136
key == other.key
3237
end
@@ -43,7 +48,7 @@ def public_mode?(redis)
4348
private
4449

4550
def subscriptions
46-
@subscriptions ||= Subscriptions.new(self, plans)
51+
@subscriptions ||= Subscriptions.new(self, plans, logger)
4752
end
4853

4954
def plans

lib/travis/owners/subscriptions.rb

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
module Travis
22
module Owners
3-
class Subscriptions < Struct.new(:owners, :config)
3+
class Subscriptions < Struct.new(:owners, :config, :logger)
4+
MSGS = {
5+
missing_plan: '[missing_plan] Plan missing from application config: %s (%s)'
6+
}
7+
48
def active?
59
subscriptions.any?
610
end
711

8-
def max_jobs
9-
@max_jobs ||= plan_limits.inject(&:+).to_i
12+
def capacity
13+
@capacity ||= plan_limits.inject(&:+).to_i
1014
end
15+
alias max_jobs capacity
1116

1217
def subscribers
1318
@subscribers ||= subscriptions.map(&:owner).map(&:login)
@@ -20,7 +25,11 @@ def plan_limits
2025
end
2126

2227
def plan_limit(plan)
23-
config[plan.to_sym]
28+
config[plan.to_sym].tap { |limit| missing_plan(plan) unless limit }
29+
end
30+
31+
def missing_plan(plan)
32+
logger.warn MSGS[:missing_plan] % [plan, owners.to_s]
2433
end
2534

2635
def plans

0 commit comments

Comments
 (0)