| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| |
| package com.cloud.utils.backoff.impl; |
| |
| import java.util.Collection; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import com.cloud.utils.NumbersUtil; |
| import com.cloud.utils.backoff.BackoffAlgorithm; |
| import com.cloud.utils.component.AdapterBase; |
| import org.apache.log4j.Logger; |
| |
| /** |
| * An implementation of BackoffAlgorithm that waits for some seconds. |
| * After the time the client can try to perform the operation again. |
| * |
| * @config |
| * {@table |
| * || Param Name | Description | Values | Default || |
| * || seconds | seconds to sleep | integer | 5 || |
| * } |
| **/ |
| public class ConstantTimeBackoff extends AdapterBase implements BackoffAlgorithm, ConstantTimeBackoffMBean { |
| long _time; |
| private final Map<String, Thread> _asleep = new ConcurrentHashMap<String, Thread>(); |
| private static final Logger LOG = Logger.getLogger(ConstantTimeBackoff.class.getName()); |
| |
| @Override |
| public void waitBeforeRetry() { |
| Thread current = Thread.currentThread(); |
| try { |
| _asleep.put(current.getName(), current); |
| Thread.sleep(_time); |
| } catch (InterruptedException e) { |
| // JMX or other threads may interrupt this thread, but let's log it |
| // anyway, no exception to log as this is not an error |
| LOG.info("Thread " + current.getName() + " interrupted while waiting for retry"); |
| } finally { |
| _asleep.remove(current.getName()); |
| } |
| return; |
| } |
| |
| @Override |
| public void reset() { |
| } |
| |
| @Override |
| public boolean configure(String name, Map<String, Object> params) { |
| _time = NumbersUtil.parseLong((String)params.get("seconds"), 5) * 1000; |
| return true; |
| } |
| |
| @Override |
| public Collection<String> getWaiters() { |
| return _asleep.keySet(); |
| } |
| |
| @Override |
| public boolean wakeup(String threadName) { |
| Thread th = _asleep.get(threadName); |
| if (th != null) { |
| th.interrupt(); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| @Override |
| public long getTimeToWait() { |
| return _time; |
| } |
| |
| @Override |
| public void setTimeToWait(long seconds) { |
| _time = seconds * 1000; |
| } |
| } |