001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.kernel.backgroundtask;
016    
017    import com.liferay.portal.DuplicateLockException;
018    import com.liferay.portal.kernel.dao.orm.ORMException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.model.BackgroundTask;
024    import com.liferay.portal.model.Lock;
025    import com.liferay.portal.service.LockLocalServiceUtil;
026    
027    /**
028     * @author Michael C. Han
029     */
030    public class SerialBackgroundTaskExecutor
031            extends DelegatingBackgroundTaskExecutor {
032    
033            public SerialBackgroundTaskExecutor(
034                    BackgroundTaskExecutor backgroundTaskExecutor) {
035    
036                    super(backgroundTaskExecutor);
037            }
038    
039            @Override
040            public BackgroundTaskResult execute(BackgroundTask backgroundTask)
041                    throws Exception {
042    
043                    Lock lock = null;
044    
045                    String owner =
046                            backgroundTask.getName() + StringPool.POUND +
047                                    backgroundTask.getBackgroundTaskId();
048    
049                    try {
050                            if (isSerial()) {
051                                    lock = acquireLock(backgroundTask, owner);
052                            }
053    
054                            BackgroundTaskExecutor backgroundTaskExecutor =
055                                    getBackgroundTaskExecutor();
056    
057                            return backgroundTaskExecutor.execute(backgroundTask);
058                    }
059                    finally {
060                            if (lock != null) {
061                                    LockLocalServiceUtil.unlock(
062                                            BackgroundTaskExecutor.class.getName(),
063                                            backgroundTask.getTaskExecutorClassName(), owner);
064                            }
065                    }
066            }
067    
068            protected Lock acquireLock(BackgroundTask backgroundTask, String owner)
069                    throws DuplicateLockException {
070    
071                    Lock lock = null;
072    
073                    while (true) {
074                            try {
075                                    lock = LockLocalServiceUtil.lock(
076                                            BackgroundTaskExecutor.class.getName(),
077                                            backgroundTask.getTaskExecutorClassName(), owner);
078    
079                                    break;
080                            }
081                            catch (ORMException orme) {
082                                    handleLockException(orme);
083                            }
084                            catch (SystemException se) {
085                                    handleLockException(se);
086                            }
087                    }
088    
089                    if (!lock.isNew()) {
090                            throw new DuplicateLockException(lock);
091                    }
092    
093                    return lock;
094            }
095    
096            protected void handleLockException(Exception e) {
097                    if (_log.isDebugEnabled()) {
098                            _log.debug("Unable to acquire acquiring lock", e);
099                    }
100    
101                    try {
102                            Thread.sleep(50);
103                    }
104                    catch (InterruptedException ie) {
105                    }
106            }
107    
108            private static Log _log = LogFactoryUtil.getLog(
109                    SerialBackgroundTaskExecutor.class);
110    
111    }