Strange behaviour of Queue object

36 views
Skip to first unread message

Markus Winter

unread,
Feb 4, 2017, 7:19:24 PM2/4/17
to jenkin...@googlegroups.com

Hi,

I encounter a strange behaviour of the Queue object.
The following code is a simple POC for the problem I have.

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Logger;

import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import hudson.Extension;
import hudson.model.ManagementLink;
import hudson.model.Queue;
import hudson.security.Permission;
import jenkins.model.Jenkins;

@Extension
public class ManagedLink extends ManagementLink
{

    private static final Logger logger = Logger.getLogger(ManagedLink.class.getName());
    private static ManagedLink instance;
    Queue.Item[] items = null;
    Queue queue;
    private static final String URL = "samplelink";
    private static final String ICON = "system-log-out.png";

    public static ManagedLink getInstance()
    {
        List<ManagementLink> list = Jenkins.getInstance().getManagementLinks();
        for (ManagementLink link : list)
        {
            if (link instanceof ManagedLink)
            {
                instance = (ManagedLink)link;
                break;
            }
        }
        return instance;
    }

    @Override
    public String getIconFileName()
    {
        return ICON;
    }

    @Override
    public String getDisplayName()
    {
        return "ManagedLink";
    }

    @Override
    public String getUrlName()
    {
        return URL;
    }

    @Override
    public String getDescription()
    {
        return "Demo For Problem";
    }

    @Override
    public Permission getRequiredPermission() {
        return Jenkins.ADMINISTER;
    }

    Queue.Item[] getQueueItems()
    {
        if (items == null)
        {
            items = Queue.getInstance().getItems();
        }
        return items;
    }

    public synchronized void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException
    {
        Jenkins.getInstance().checkPermission(getRequiredPermission());

        items = Queue.getInstance().getItems();
        logger.info("Queue length in doIndex: " + items.length);
        queue = Queue.getInstance();

        ExecutorService service = Executors.newSingleThreadExecutor();
        service.submit(new MyRunner());

        rsp.sendRedirect2(req.getContextPath() + "/manage");
    }

    class MyRunner implements Runnable
    {
        @Override
        public void run()
        {
            logger.info("Queue length in Runnable from queue object from doIndex: " + queue.getItems().length);
            logger.info("Queue length in Runnable with direct access to Queue: "
                    + Queue.getInstance().getItems().length);
            logger.info("Queue length in Runnable with instance variable direct access  : " + items.length);
            logger.info("Queue length in Runnable with instance variable via method : "
                    + ManagedLink.getInstance().getQueueItems().length);
        }
    }
}

Running this code in Jenkins on Windows, when there are entries in the queue, I get the expected length.
But when I run this code inside my Linux VM, the Queue object is returning 0 for the length:

Feb 05, 2017 12:16:02 AM INFO ManagedLink doIndex
Queue length in doIndex: 1
Feb 05, 2017 12:16:02 AM INFO ManagedLink$MyRunner run
Queue length in Runnable from queue object from doIndex: 0
Feb 05, 2017 12:16:02 AM INFO ManagedLink$MyRunner run
Queue length in Runnable with direct access to Queue: 0
Feb 05, 2017 12:16:02 AM INFO ManagedLink$MyRunner run
Queue length in Runnable with instance variable direct access  : 1
Feb 05, 2017 12:16:02 AM INFO ManagedLink$MyRunner run
Queue length in Runnable with instance variable via method : 1


Strange thing is as well that when I run unit tests on Linux, it works fine.

This happens on latest 2.32.2 Jenkins with openjdk 8 on Opensuse but I can also observe this with a 1.609.3 Jenkins running with SAP JDK8
On Windows running with the JDK that comes with the Jenkins installer (java 8).

Anyone has an idea what could be the reason for this?

Regards
Markus

Oleg Nenashev

unread,
Feb 4, 2017, 8:24:41 PM2/4/17
to Jenkins Developers, m_wi...@gmx.de
Hi,

I see no logic, which actually submits something to the queue. So I am not sure what is the execution profile.

If you submit the a short task to the queue, the result is easy to explain. Starting from 1.609.x, Jenkins Queue has a snapshoting engine, which reduce the load on the queue and prevents interlocks between queue maintenance logic and WebUI.

So methods 1, 4, and 5 effectively get snapshot reference, which they use in their logic. Methods 3 and 4 work with the queue directly, so they may be getting a renewed snapshot, where the queue task has already exited the queue. Then it may easily have 0.

BR, Oleg

воскресенье, 5 февраля 2017 г., 1:19:24 UTC+1 пользователь Markus Winter написал:

Markus Winter

unread,
Feb 4, 2017, 9:07:45 PM2/4/17
to Jenkins Developers, o.v.ne...@gmail.com
Hi,

Actually, I create a job that sleeps for 30 seconds without concurrent execution and start it. Once running it start it again. So there is exactly one entry in the queue.
Now while the job is in the queue I click on the management link. And I get different behaviour depending on OS it seems.
I also added output that sleeps for 2 seconds after starting the Runnable and then print the queue size.
And it is always 1 as expected.

I have one idea:
Could this be a permission problem that behaves differently on Windows and Linux?

Regards
Markus

Markus Winter

unread,
Feb 4, 2017, 9:15:12 PM2/4/17
to Jenkins Developers, o.v.ne...@gmail.com

yes it is a permission problem. I had security disabled on my local PC, while it was enabled in the VM.

Problem solved

Reply all
Reply to author
Forward
0 new messages