Синхронизация выполняемых задач на NLB-кластере (вопрос)

Одним прекрасным днём появилась как-то задача - обеспечить синхронизацию обрабатываемых записей. Требовалось исключить повторную обработку, которая, к тому же, занимала значительное время.

Решение нашлось очень быстро - создание именованного мьютекса:

using System.Threading;
using System.Security.Principal;
using System.Security.AccessControl;

...

public SomeResponseType HandleRecord(string recordId)
{
	SomeResponseType result = null;
	bool hasHandle = false;

	// создаём Mutex с кодом запис вместо имени
	Mutex m = CreateMutex(recordId);
	hasHandle = m.WaitOne(100, false);
	
	if (!hasHandle)
	{
		// Определили, что кто-то уже обрабатывает запись с этим кодом
		// возвращаем второму клиенту сообщение 'Данная запись уже в обработке'
		return ...
	}

	try
	{
		// это единственный вызов - обрабатываем запись
		...
	}
	catch (Exception ex)
	{
		...
	}
	finally
	{
		if (hasHandle)
		{
			m.ReleaseMutex(); 
		}
	}

	return result;
}

/// <summary>
/// Создаём глобальный именованный Mutex 
/// + раздаём права на него другим пользователям.
/// </summary>
/// <param name="recordId">GUID записи, который станет именем мьютекса</param>
/// <returns></returns>
private static Mutex CreateMutex(string recordId)
{
	var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);

	// MutexSecurity позволяет задать права на создаваемый объект
	// мьютекса, чтобы другие пользователи могли иметь к нему доступ
	var mutexsecurity = new MutexSecurity();
	
	mutexsecurity.AddAccessRule(
		new MutexAccessRule(
			sid,
			MutexRights.FullControl,
			AccessControlType.Allow));

	mutexsecurity.AddAccessRule(
		new MutexAccessRule(
			sid,
			MutexRights.ChangePermissions,
			AccessControlType.Deny));

	mutexsecurity.AddAccessRule(
		new MutexAccessRule(
			sid,
			MutexRights.Delete,
			AccessControlType.Deny));

	bool created;

	// создаём Mutex с идентификатором обрабатываемой записи вместо имени
	return new Mutex(false, "Global\\" + recordId, out created, mutexsecurity);
}

Всё прекрасно работало, пока не было перенесено с одиночного сервера на NLB-кластер.

Почему сломалось? Понятно, что при распределении клиентских запросов на разные сервера найти мьютекс на другой машине не представляется возможным, каким бы глобальным он не был.

Хочется выслушать теперь мнение матёрых читателей: какое решение можно использовать на NLB для данной задачи?

Ваша оценка: Пусто Средняя: 2 (26 votes)

Комментарии

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступны HTML теги: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и параграфы переносятся автоматически.
  • Syntax highlight code surrounded by the {syntaxhighlighter SPEC}...{/syntaxhighlighter} tags, where SPEC is a Syntaxhighlighter options string or "class="OPTIONS" title="the title".

Подробнее о форматировании

Image CAPTCHA
Enter the characters shown in the image.
Работает на Drupal, система с открытым исходным кодом.