Class: Kamaze::Project::Tools::ProcessLocker

Inherits:
BaseTool show all
Defined in:
lib/kamaze/project/tools/process_locker.rb

Overview

Process Locker

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

This class inherits a constructor from Kamaze::Project::Tools::BaseTool

Instance Attribute Details

#fsModule<FileUtils> (readonly, protected)

Returns:

  • (Module<FileUtils>)


98
99
100
# File 'lib/kamaze/project/tools/process_locker.rb', line 98

def fs
  @fs
end

#inflectorDry::Inflector (readonly, protected)

Returns:

  • (Dry::Inflector)


95
96
97
# File 'lib/kamaze/project/tools/process_locker.rb', line 95

def inflector
  @inflector
end

#lockdirString

Returns:

  • (String)


27
28
29
# File 'lib/kamaze/project/tools/process_locker.rb', line 27

def lockdir
  @lockdir
end

#observer_peersHash|nil (readonly, protected) Originally defined in module Concern::Observable

Returns:

  • (Hash|nil)

Class Method Details

.method_missing(method, *args, &block) ⇒ Object



77
78
79
80
81
82
83
# File 'lib/kamaze/project/tools/process_locker.rb', line 77

def method_missing(method, *args, &block)
  if respond_to_missing?(method)
    return self.new.public_send(method, *args, &block)
  end

  super
end

.respond_to_missing?(method, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


85
86
87
88
89
# File 'lib/kamaze/project/tools/process_locker.rb', line 85

def respond_to_missing?(method, include_private = false)
  return true if self.new.respond_to?(method, include_private)

  super(method, include_private)
end

Instance Method Details

#lock(lockname) ⇒ Object

Manage lock on given block

Returns:



46
47
48
# File 'lib/kamaze/project/tools/process_locker.rb', line 46

def lock(lockname)
  mklock(lockname).acquire { yield }
end

#lock!(lockname) ⇒ Object

Manage lock on given block

Returns:

Raises:

  • (Errno::EALREADY)
  • (ProcessLock::AlreadyLocked)


55
56
57
58
59
60
61
62
# File 'lib/kamaze/project/tools/process_locker.rb', line 55

def lock!(lockname)
  mklock(lockname).acquire! { yield }
rescue ProcessLock::AlreadyLocked
  # noinspection RubyResolve
  raise Errno::EALREADY if mklock(lockname).alive?

  raise
end

#mklock(lockname) ⇒ ProcessLock (protected)

Parameters:

  • lockname (String)

Returns:

  • (ProcessLock)


115
116
117
# File 'lib/kamaze/project/tools/process_locker.rb', line 115

def mklock(lockname)
  mktemp(lockname).yield_self { |lockfile| ProcessLock.new(lockfile) }
end

#mktemp(lockname) ⇒ Pathname (protected)

Create a temporary file

Parameters:

  • lockname (String)

Returns:

  • (Pathname)


123
124
125
# File 'lib/kamaze/project/tools/process_locker.rb', line 123

def mktemp(lockname)
  Pathname.new(lockname.to_s).basename('.*').yield_self { |fp| mktmpdir.join(fp) }
end

#mktmpdir(**options) ⇒ Pathname (protected)

Create tmpdir

Returns:

  • (Pathname)


130
131
132
133
134
135
136
# File 'lib/kamaze/project/tools/process_locker.rb', line 130

def mktmpdir(**options)
  self.tmpdir.tap do |tmpdir|
    options[:mode] ||= 0o700

    fs.mkdir_p(tmpdir, **options)
  end
end

#mutable_attributesObject



29
30
31
# File 'lib/kamaze/project/tools/process_locker.rb', line 29

def mutable_attributes
  [:lockdir]
end

#setupObject (protected)



100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/kamaze/project/tools/process_locker.rb', line 100

def setup
  @fs ||= FileUtils
  @inflector ||= Kamaze::Project::Inflector.new

  unless lockdir # rubocop:disable Style/GuardClause
    self.lockdir = lambda do
      return Kamaze::Project.instance.name if Kamaze::Project.instance

      Digest::SHA1.hexdigest(__FILE__) # Does not avoid collision if package is globally installed
    end.call
  end
end

#tmpdirPathname

Get tmpdir where lock files are stored.

Returns:

  • (Pathname)


67
68
69
70
71
72
73
74
# File 'lib/kamaze/project/tools/process_locker.rb', line 67

def tmpdir
  require 'tmpdir' unless Dir.respond_to?(:tmpdir)

  Pathname.new(Dir.tmpdir).join('%<libname>s.%<uid>s' % { # @formatter:off
    libname: inflector.underscore(self.class.name).split('/')[0..1].join('-'),
    uid: Etc.getpwnam(Etc.getlogin).uid, # @formatter:on
  }, lockdir)
end