Commit Graph

24 Commits

Author SHA1 Message Date
Antoine Musso 0c47b4292d Retire the project on OpenDev
It has been migrated to the Jenkins community:
https://github.com/jenkinsci/gearman-plugin/

Depends-On: Ib6010d7ce85a934501c50a53e9ac78dcf74bc403
Change-Id: I0c84db2ad3fbb4d9f0eff793a0159c6ed3a8e25c
2021-05-27 17:23:43 +02:00
Khai Do a5164d65a4 Update to Jenkins LTS 1.625.3 and fix function registration
Using a newer Jenkins LTS (ver 1.625.3) did not work with the
gearman-plugin. Gearman function registeration wasn't working
correct because Computer.currentComputer()[1] and getInstance()[2]
methods seemed to always return null on initialization of the
plugin. The Jenkins.getActiveInstance method (introduced in
Jenkins-1.589)[3] works more reliably.

[1] http://javadoc.jenkins-ci.org/hudson/model/Node.html#getNodeName()
[2] http://javadoc.jenkins-ci.org/jenkins/model/Jenkins.html#getActiveInstance()
[3] e6c2e16f7a

Change-Id: I1534beda9c39a9d15da4d7b96f17e7b75699a631
2016-01-24 06:14:52 -08:00
James E. Blair 2cb540bf51 Use more fine-grained synchronization in GearmanProxy
This undoes some of the previous change.  In particular, calling
something that could affect a NodeAvailabilityMonitor's lock
(eg in canTake or the init methods in createExecutorWorkersOnNode)
can deadlock on trying to obtain the Queue lock while holding the
GearmanProxy lock.

Instead, lock on just the handle lists where necessary, and try
to do serious work outside of that lock.

Change-Id: I4c1ed6c7a4f5586c1034651a649bbbd420eacdd7
2013-08-14 14:50:14 -07:00
James E. Blair c97253eff5 Rework starting/stopping executors
There was at least one error, likely a race condition, with the
previous code which could cause more than one ExecutorWorkerThread for
a node to be spawned.  In particular, I think the bogus comparison in
ComputerListenerImpl may have a large part in that (it checked to see
if a _Computer_ object was in a list of _Thread_ objects).

To improve reliability around adding and removing nodes, all related
functionality is moved to the GearmanProxy class.  Any methods (most
of them) that have to do with starting or stopping worker threads are
synchronized on the GearmanProxy monitor (the important parts of most
threads were already synchronized on the worker list before, so this
should not be much of a performance change).

The methods that start management and executor threads now do their
own checking to verify that such threads do not already exist, making
it so that calling them is more idempotent.  Existing checks external
to the class have been removed (these were likely somewhat racy).

To avoid keeping redundant data structures, the node availability list
is removed, and instead if we need to find an availability object, we
walk the list of worker threads and compare to their nodes.  Because
we do this so much, the list of worker and management threads are
changed to use those explicit classes instead of
AbstractWorkerThreads.

The accessor methods for the internal lists of worker threads is
removed to ensure that they are only managed through GearmanProxy.
This changed some unit tests and required the removal of one complete
test (which was not doing much more than verifying the addition
operator).

Also, when stopping ExecutorWorkerThreads, stop all of the ones
associated with a node.

When a computer goes offline, Computer.getNode() returns null, so we
can't know which workers should be deleted.  Instead of using Nodes as
keys for our workers, use Computers instead and change everything to
use Computer (most functions needed Computer rather than Node anyway),
and in the few remaining places where a Node is needed, convert the
other direction.

Change-Id: Ia5084579317f972400069cc3e84db4e0b6560a80
2013-08-13 11:31:50 -07:00
James E. Blair 9bacb54664 Avoid holding locks on gewtHandles.
Some of the operations we were doing on worker threads while
iterating over the list of worker threads were fairly deep and
themselves required locks.  Instead, try to hold the lock on
worker thread lists as short as possible.  Snapshot them and
iterate over the snapshot when doing complicated tasks.

Change-Id: I4c257e83b2a2f985bf571f4f64e2db44d2d17e3d
2013-06-15 10:15:43 -07:00
James E. Blair 2ba8b61b3a More deadlock fixes.
It's possible that some InterruptedExceptions were being hidden by
the GrabJobEventHandler, which must catch those and not throw them.
So wherever we call driveSessionIO, check to make sure that we are
still supposed to be running afterwords.

Make sure all other places where InterruptedException is caught
do something reasonable with it.

Remove printStackTrace calls and replace with logging calls.

Change-Id: I0790eece8582c1ee2cd28e8866bfd4a9d5d700cd
2013-06-14 21:22:27 -07:00
James E. Blair 6041401766 Handle mutex scheduling from Gearman or Jenkins.
Every node (slave or master) gets an AvailabilityMonitor that
handles mutually exclusive access to scheduling builds on that
node.  If Jenkins wants to run a build on the node, it will only
be able to do so if we are not waiting for a response to a
GRAB_JOB packet from Gearman.  Likewise, immediately before
sending a GRAB_JOB, we lock the monitor and only unlock it if
we either get a NO_JOB response, or after the job we were just
assigned starts building.

(As an exception to the above rule, since Jenkins will apply the
same scheduling veto logic to the build that we request via Gearman,
(while we still hold the lock) we tell the monitor to expect a request
for that build from Jenkins and we permit Jenkins to build it even
if the lock is held.)

Change-Id: Iae03932aef4b503c69699b99d38a6fc2691fb02e
2013-06-13 12:42:51 -07:00
James E. Blair 858fb155fe Don't grab a job when executors are busy.
Jobs can be triggered by non-gearman sources, sadly.  This makes the gearman
plugin aware of when executors are busy and it will refrain from grabbing a
job from gearman in those circumstances.

It's far from perfect, but should at least handle the most likely cases where
a job is already running an an executor.

Change-Id: If993c6d6bc63ed89b385d2e5bb41762ef84a429f
2013-06-11 16:04:09 -07:00
zaro0508 18a3fa68cc always run management worker
This commit is a fix to bug 1185952.

While the jenkins host is running its master node may
be in a disabled state (master has 0 executors) however the
host should still be able to run a management worker and
communicate with a Gearman Server.  This commit makes
sure that the manaegement worker runs regardless
the master node's state.

This commit also makes sure that we are setting the management
worker's name to something.

Change-Id: I871019fadde47787cfe20bec666e24d242728f30
2013-06-11 15:18:04 -07:00
zaro0508 78abc3d903 Added a Stop() method to handle stopping executor worker threads.
fix for bug 1181569

Refactored how stop was handled.  Removing thread and stopping thread
in the same syncronized loop was causing concurrent modification error.
Needed to seperate the actions for it to work.

Change-Id: I99b676f377842826f9e6a847cfeff76be91c8299
2013-05-31 11:53:56 -07:00
zaro0508 09241a692a remove comment and use generic AbstractWorkerThread object.
Change-Id: Ibe3631635e24f9f54e10179f88d90e4e190b43a8
2013-05-21 10:04:12 -07:00
zaro0508 42c95ac958 add gearman worker to set build descriptions
This commit adds another management worker for setting a build's descriptions.
The worker will lookup the build by it's build_id (jobName:jobId)
and if it can find it then will set the description and return with COMPLETED.
If it cannot find the build or cannot set the description for any reason
it will return FAILED.

This commit also adds teh build_id to the data returned by the StartJobWorker.

Usage:

  client = gear.Client()
  client.addServer('localhost')
  client.waitForServer()
  job_name = 'set_description:JenkinsHostName'
  data = {'build_id':"pep8:2013-05-15_17-32-07",'description':"<h1>My Test Build</h1>"}
  job = gear.Job(job_name, simplejson.dumps(data))
  client.submitJob(job)

Change-Id: I4990772d591d27bbb3b4f20abfb4d988077b4995
2013-05-18 11:26:15 -07:00
zaro0508 0de925f6d8 fix for bug 1162887
Users no longer need to disable the plugin to connect to
a different gearman server.

Along with this commit I changed the 'launchWorker' plugin config name to
'enablePlugin' because enabling plugin is distinct from running gearman workers.

Change-Id: Ia81d78da3dbdc83fd46dd7f5d40ccb9aca3af97f
2013-05-01 10:20:45 -07:00
James E. Blair 4e560245c0 Reference jenkins master in workers.
The "stop:" function should be qualified by the name of the jenkins master
to make it globally unique (eg "stop:jenkins.example.com").

Supply the name of the master in the WORK_DATA that is sent to the client
when the job starts building so that the client can direct a subsequent
"stop:" request to the right worker.

Change-Id: I0112b84ae614ce4faaed880ea3d1073674dfe5fe
2013-04-29 13:25:58 -07:00
James E. Blair 20844c7e46 Add local GearmanWorker.
Add a package local implementation of something like the GearmanWorker from
java-gearman (based on GearmanWorkerImpl).

It is much simpler than the existing GearmanWorkerImpl and is more suited to
the way we need to use it in the Jenkins plugin.  It assumes jobs are always
changed in batches, and only changes jobs at the top of the event loop (not
when a job is running).

The worker threads are updated to only request job changes when there is an
actual difference.

WORK_STATUS events are sent every 10 seconds while a job is running.

run-fast is updated to only remove the gearman plugin from the work directory,
preserving any other plugins that may be installed.

This isn't very elegant, but is a start and broadly demonstrates what we need
the plugin to do.

Change-Id: I26df504534ec50f03c9e0ef772a709046cf88a23
2013-04-22 10:29:03 -07:00
zaro0508 95772760dd tests for GearmanProxy
Added new tests for GearmanProxy.  Also changed method names
init_workers and stop_all to initWorkers and stopAll. more in line
with the java-ish camelcase convention.

Change-Id: I081236d334afd1c57aab8213b80e080dc5dccb53
2013-03-28 14:31:11 -07:00
zaro0508 a9e5a4f636 make GearmanProxy a singleton
Refactor GearmanProxy to be a singleton instead of using static fields
and methods to manage thread states.

Change-Id: I8d84778f0e0d7020bb08087be29808f46aff8786
2013-03-28 14:31:11 -07:00
zaro0508 9c9acdbdba fix executor names, clean up, remove code duplication
src/main/java/hudson/plugins/gearman/AbstractWorkerThread.java
    Removed Id field, it was initially added because I thought it was the plugin's
    responsibility to cancel jobs that are on the gearman queue.  We've decided that
    it will be the client (zuul or otherwise) responsibility to cancel jobs from the gearman
    queue.  The gearman plugin will cancel jobs that have already been put on the
    jenkins queue.

src/main/java/hudson/plugins/gearman/ComputerListenerImpl.java
src/main/java/hudson/plugins/gearman/ExecutorWorkerThread.java
src/main/java/hudson/plugins/gearman/GearmanPluginConfig.java
src/main/java/hudson/plugins/gearman/GearmanProxy.java
src/main/java/hudson/plugins/gearman/ManagementWorkerThread.java
src/main/java/hudson/plugins/gearman/StartJobWorker.java
    Refactor to reduce code duplication. Consolidated creation of management worker and
    executor workers.  Added a fix so that executors spawned on master node
    is named 'master-manager' for the manager and 'master-exec-#' for executors

src/test/java/hudson/plugins/gearman/ManagementWorkerThreadTest.java
    Added test to make sure worker name is set correctly

src/main/java/hudson/plugins/gearman/GearmanPluginUtil.java
src/test/java/hudson/plugins/gearman/GearmanPluginUtilTest.java
    Useful utils for the gearman plugin with tests

Change-Id: I96e097dc0dbf5cd78e5e82af584976085aee61b3
2013-03-22 15:47:19 -07:00
zaro0508 5592122272 fix node state transitions and threading improvements
This checkin does the following:
1. Makes the plugin more thread safe.
2. Exposes the node object in the ExecutorWorkerThread
 to allow gearman function updates to be more efficient and makes it
 simpler to track new slaves vs existing slaves in the system.
3. Treat slave disconnect the same as a slave deletion.  Disconnect will
 stop the associated executor worker thread.  Connect will spawn a new
 thread for the slave.  This more closely matches how jenkins
 treats slave states.

src/main/java/hudson/plugins/gearman/ComputerListenerImpl.java
src/main/java/hudson/plugins/gearman/ExecutorWorkerThread.java
src/main/java/hudson/plugins/gearman/GearmanPluginConfig.java
    Expose the node to listeners for updating gearman functions
    Treat slave disconnect the same as a slave deletion

src/main/java/hudson/plugins/gearman/GearmanProxy.java
    Made lists into syncronized list

src/main/java/hudson/plugins/gearman/ProjectListener.java
    Syncronized iteration of lists

Change-Id: I7d7a40ec7783e3e7f21c9974dad9159beee6b985
2013-03-18 08:45:17 -07:00
zaro0508 c461e204f2 misc doc and logging updates
Checkin to change README from txt to rst format.
Jenkins seems to hijack logging so i've removed all of the
logging specific bindings that were added previously.
I also added "----" to begining of this plugin's logging
messages so i could easily keep track of them.

Change-Id: Ibd8c56af5b9ad18152bcb0d3ff0c41168a6d2fd1
2013-03-12 10:51:24 -07:00
zaro0508 1eeb5dd99d make gearman-plugin enable/disable state persistant across jenkins restart
This checkin will enable the gearman-plugin to be in the same state
as it was configured to before jenkins shutdown.  The gearman plugin will
now startup in ether enabled or disabled state.  Enabled means that
the plugin will automatically spawn all the threads and register all the
functions depending on the state of the slaves, projects and labels.
Disabled means that no workers are spawned and no functions are registers.
When in diabled state user can manually enable the gearman-plugin from the
jenkins configuration page.  If the plugin is enabled on startup the user can
disable it from the jenkins global configuration page, which will stop
all of the workers.

src/main/java/hudson/plugins/gearman/ComputerListenerImpl.java
    automate the spawning of executors when master comes online.
    add license info

src/main/java/hudson/plugins/gearman/GearmanPluginConfig.java
    remove setting to put gearman-plugin in disable state on startup.

src/main/java/hudson/plugins/gearman/GearmanProxy.java
    Add method to get the list of management executors
    changed thead list from Stack to ArrayList object

Change-Id: Iea20dd244b322de0bf75eff3b31a4f70ed688282
2013-03-08 13:26:54 -08:00
zaro 8ee129e6be make thread safe
This checkin attempts to make gearman plugin objects thread safe.

src/main/java/hudson/plugins/gearman/SaveableListenerImpl.java
   Decided that this was not needed.

src/main/java/hudson/plugins/gearman/GearmanPluginConfig.java
   Added method to allow other objects to access gearman server
   launchWorker, host, and port settings

src/main/java/hudson/plugins/gearman/GearmanPluginUtil.java
   Useful utilities for this plugin

src/main/java/hudson/plugins/gearman/AbstractWorkerThread.java
src/main/java/hudson/plugins/gearman/ComputerListenerImpl.java
src/main/java/hudson/plugins/gearman/ProjectListener.java
src/main/java/hudson/plugins/gearman/GearmanProxy.java
   Made object private and added syncronized setters and getters

Change-Id: I04ca6a275ba8184bd18cf8954d07b94d02b2a47d
2013-03-05 09:51:10 -08:00
zaro 0e81e014da decouple gearman from the gearman configuration
This change is to create a new object to store Gearman
objects and state info.

src/main/java/hudson/plugins/gearman/GearmanProxy.java
  created to keep Gearman state info.

src/main/java/hudson/plugins/gearman/GearmanPluginConfig.java
  simplied this class by removing the core gearman stuff out to
  a GearmanProxy.java class

src/main/java/hudson/plugins/gearman/Constants.java
  Use one logger instead of two.  updated logger reference in all
  of the other files in this checkin

src/main/java/hudson/plugins/gearman/ProjectListener.java
src/main/java/hudson/plugins/gearman/StartJobWorker.java
src/main/java/hudson/plugins/gearman/StopJobWorker.java
src/main/java/hudson/plugins/gearman/ComputerListenerImpl.java
  update references to changed class and methods

Change-Id: I879cdb8839c8b5437bccf6d7e1602c33eff434a6
2013-03-05 09:51:10 -08:00
zaro 5823f98b5c dyanmic registration of gearman functions
Initial checkin for dynamic gearman function registration.
This is not thread safe but does work for most of the use cases
where we want to update gearman worker threads and functions.

functions are getting updated for the following scenarios:
1. project name change
2. project label change
3. project delete
4. project create
5. slave creation - spawns a new worker thread
6. slave deletion - stops an existing worker thread
7. slave state change online/offline
8. slave connection change connect/disconnect

Not working:
1. project state change (disable/enable)
2. master and slave node label change
3. master and slave node executor change

Change-Id: I8e79519198224fc4c93fd16c741fb7de568077b9
2013-03-05 09:51:10 -08:00