# Job reentrancy avoidance proposal

**URL:** <https://discuss.hangfire.io/t/job-reentrancy-avoidance-proposal/607>\
**Category:** question\
**Created:** [January 28, 2015, 10:59am UTC](https://discuss.hangfire.io/t/job-reentrancy-avoidance-proposal/607 "2015-01-28T10:59:13Z")\
**Posts on this page:** 1\
**Showing post:** 8

<div class="post-metadata">

**Author:** ![Stefan\_Sieber](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/stefan_sieber/32/293_2.png) [@Stefan\_Sieber](https://discuss.hangfire.io/u/Stefan_Sieber)\
**Post date:** [October 6, 2015, 1:01pm UTC](https://discuss.hangfire.io/t/job-reentrancy-avoidance-proposal/607/8 "2015-10-06T13:01:11Z")

</div>

In case someone else has the same problems, we went ahead and implemented an own JobFilterAttribute which we use instead of DisableConcurrentExecutionAttribute. The code is mostly the same as proposed by @Domonkos (thx!) :

```
/// <summary>
/// Attribute to skip a job execution if the same job is already running.
/// Mostly taken from: http://discuss.hangfire.io/t/job-reentrancy-avoidance-proposal/607
/// </summary>
public class SkipConcurrentExecutionAttribute : JobFilterAttribute, IServerFilter
{
	private static readonly Logger logger = LogManager.GetCurrentClassLogger();

	private readonly int _timeoutInSeconds;

	public SkipConcurrentExecutionAttribute(int timeoutInSeconds)
	{
		if (timeoutInSeconds < 0) throw new ArgumentException("Timeout argument value should be greater that zero.");

		_timeoutInSeconds = timeoutInSeconds;
	}

	public void OnPerforming(PerformingContext filterContext)
	{
		var resource = String.Format(
							 "{0}.{1}",
							filterContext.Job.Type.FullName,
							filterContext.Job.Method.Name);

		var timeout = TimeSpan.FromSeconds(_timeoutInSeconds);

		try
		{
			var distributedLock = filterContext.Connection.AcquireDistributedLock(resource, timeout);
			filterContext.Items["DistributedLock"] = distributedLock;
		}
		catch (Exception)
		{
			filterContext.Canceled = true;
			logger.Warn("Cancelling run for {0} job, id: {1} ", resource, filterContext.JobId);
		}
	}

	public void OnPerformed(PerformedContext filterContext)
	{
		if (!filterContext.Items.ContainsKey("DistributedLock"))
		{
			throw new InvalidOperationException("Can not release a distributed lock: it was not acquired.");
		}

		var distributedLock = (IDisposable)filterContext.Items["DistributedLock"];
		distributedLock.Dispose();
	}
}
```

---

_[View the full topic](https://discuss.hangfire.io/t/job-reentrancy-avoidance-proposal/607)._
