scout 5.5.8 → 5.5.9.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ # 5.5.9
2
+
3
+ * Locking data file when writing.
4
+
1
5
  # 5.5.8
2
6
 
3
7
  * Passing server_name for install + test commands so https_proxy is used.
@@ -10,3 +10,4 @@ require "scout/server"
10
10
  require "scout/streamer"
11
11
  require "scout/daemon_spawn"
12
12
  require "scout/streamer_daemon"
13
+ require "scout/data_file"
@@ -0,0 +1,50 @@
1
+ # Used to perform locked, atomic writes to the data file.
2
+ module Scout
3
+ class DataFile
4
+ attr_accessor :path, :logger
5
+ attr_reader :data
6
+
7
+ def initialize(path,logger)
8
+ @path = path
9
+ @logger = logger
10
+ end
11
+
12
+ # atomic_write first writes to the tmp file.
13
+ def tmp_path
14
+ path+'.tmp'
15
+ end
16
+
17
+ # saves the data file by (1) locking the file at +path+ to ensure other processes
18
+ # don't overlap (2) using an atomic write to ensure other processes always read a complete file.
19
+ def save(content)
20
+ lock do
21
+ atomic_write(content)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def lock
28
+ File.open(path, File::RDWR | File::CREAT) do |f|
29
+ begin
30
+ f.flock(File::LOCK_EX)
31
+ yield
32
+ ensure
33
+ f.flock(File::LOCK_UN)
34
+ end
35
+ end
36
+ rescue Errno::ENOENT, Exception => e
37
+ logger.error("Unable to access data file [#{e.message}]")
38
+ end
39
+
40
+ # Uses an Atomic Write - first writes to a tmp file then replace the history file.
41
+ # Ensures reads on the history file don't see a partial write.
42
+ def atomic_write(content)
43
+ File.open(tmp_path, 'w+') do |f|
44
+ f.write(content)
45
+ end
46
+ FileUtils.mv(tmp_path, path)
47
+ end
48
+
49
+ end
50
+ end
@@ -46,6 +46,7 @@ module Scout
46
46
  @account_public_key_path = File.join(@local_plugin_path, "scout_rsa.pub")
47
47
  @history_tmp_file = history_file+'.tmp'
48
48
  @plugin_config = load_plugin_configs(@plugin_config_path)
49
+ @data_file = Scout::DataFile.new(@history_file,@logger)
49
50
 
50
51
  # the block is only passed for install and test, since we split plan retrieval outside the lockfile for run
51
52
  if block_given?
@@ -56,7 +57,6 @@ module Scout
56
57
  end
57
58
 
58
59
  def refresh?
59
- #info "called refresh: ping_key=#{ping_key}"
60
60
  return true if !ping_key or account_public_key_changed? # fetch the plan again if the account key is modified/created
61
61
 
62
62
  url=URI.join( @server.sub("https://","http://"), "/clients/#{ping_key}/ping.scout")
@@ -65,7 +65,7 @@ module Scout
65
65
  if @history["plan_last_modified"] and @history["old_plugins"]
66
66
  headers["If-Modified-Since"] = @history["plan_last_modified"]
67
67
  end
68
- get(url, "Could not ping #{url} for refresh info", headers) do |res|
68
+ get(url, "Could not ping #{url} for refresh info", headers) do |res|
69
69
  @streamer_command = res["x-streamer-command"] # usually will be nil, but can be [start,abcd,1234,5678|stop]
70
70
  if res.is_a?(Net::HTTPNotModified)
71
71
  return false
@@ -545,21 +545,15 @@ module Scout
545
545
  # creates a blank history file
546
546
  def create_blank_history
547
547
  debug "Creating empty history file..."
548
- File.open(@history_file, "w") do |file|
549
- YAML.dump({"last_runs" => Hash.new, "memory" => Hash.new, "last_client_key" => client_key}, file)
550
- end
548
+ @data_file.save(YAML.dump({"last_runs" => Hash.new, "memory" => Hash.new, "last_client_key" => client_key}))
551
549
  info "History file created."
552
550
  end
553
551
 
554
552
  # Saves the history file to disk.
555
- #
556
- # Uses an Atomic Write - first writes to a tmp file then replace the history file.
557
- # Ensures reads on the history file don't see a partial write.
558
553
  def save_history
559
554
  debug "Saving history file..."
560
555
  @history['last_client_key'] = client_key
561
- File.open(@history_tmp_file, "w") { |file| YAML.dump(@history, file) }
562
- FileUtils.mv(@history_tmp_file, @history_file)
556
+ @data_file.save(YAML.dump(@history))
563
557
  info "History file saved."
564
558
  end
565
559
 
@@ -1,3 +1,3 @@
1
1
  module Scout
2
- VERSION = "5.5.8"
2
+ VERSION = "5.5.9.pre"
3
3
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.5.8
5
- prerelease:
4
+ version: 5.5.9.pre
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Andre Lewis
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-09-10 00:00:00.000000000 Z
14
+ date: 2012-09-18 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: elif
18
- requirement: &2157721580 !ruby/object:Gem::Requirement
18
+ requirement: &2161260300 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,7 +23,7 @@ dependencies:
23
23
  version: '0'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *2157721580
26
+ version_requirements: *2161260300
27
27
  description: ! 'Scout makes monitoring and reporting on your web applications as flexible
28
28
  and simple as possible.
29
29
 
@@ -53,6 +53,7 @@ files:
53
53
  - lib/scout/command/test.rb
54
54
  - lib/scout/command/troubleshoot.rb
55
55
  - lib/scout/daemon_spawn.rb
56
+ - lib/scout/data_file.rb
56
57
  - lib/scout/plugin.rb
57
58
  - lib/scout/plugin_options.rb
58
59
  - lib/scout/scout_logger.rb
@@ -232,9 +233,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
232
233
  required_rubygems_version: !ruby/object:Gem::Requirement
233
234
  none: false
234
235
  requirements:
235
- - - ! '>='
236
+ - - ! '>'
236
237
  - !ruby/object:Gem::Version
237
- version: '0'
238
+ version: 1.3.1
238
239
  requirements: []
239
240
  rubyforge_project: scout
240
241
  rubygems_version: 1.8.10