Стратегия доступа к файлу в многопоточной среде (веб-приложение)

Часть ответа заключается в том, чтобы хранить индекс имен пользователей, которые вы проверяете в своих правилах безопасности:

app : {
    users: {
       "some-user-uid": {
            email: "test@test.com"
            username: "myname"
       }
    },
    usernames: {
        "myname": "some-user-uid"
    }
}

Таким образом узел usernames сопоставляет имя пользователя с uid. Он по существу читает, что «имя пользователя« myname »принадлежит« some-user-uid ».

С помощью этой структуры данных ваши правила безопасности могут проверить, есть ли уже запись для данного имени пользователя:

"users": {
  "$uid": {
    ".write": "auth !== null && auth.uid === $uid",
    ".read": "auth !== null && auth.provider === 'password'",
    "username": {
      ".validate": "
        !root.child('usernames').child(newData.val()).exists() ||
        root.child('usernames').child(newData.val()).val() == $uid"
    }
  }
}

Это подтверждает, что имя пользователя еще не заявлено кем-либо еще, или оно заявлено текущим пользователем.

6
задан Community 9 September 2008 в 22:13
поделиться

4 ответа

Вот код, который я использую, чтобы удостовериться, что файл не заблокирован другим процессом. Это не является на 100% надежным, но это сделало задание большую часть времени:

    /// <summary>
    /// Blocks until the file is not locked any more.
    /// </summary>
    /// <param name="fullPath"></param>
    bool WaitForFile(string fullPath)
    {
        int numTries = 0;
        while (true)
        {
            ++numTries;
            try
            {
                // Attempt to open the file exclusively.
                using (FileStream fs = new FileStream(fullPath,
                    FileMode.Open, FileAccess.ReadWrite, 
                    FileShare.None, 100))
                {
                    fs.ReadByte();

                    // If we got this far the file is ready
                    break;
                }
            }
            catch (Exception ex)
            {
                Log.LogWarning(
                   "WaitForFile {0} failed to get an exclusive lock: {1}", 
                    fullPath, ex.ToString());

                if (numTries > 10)
                {
                    Log.LogWarning(
                        "WaitForFile {0} giving up after 10 tries", 
                        fullPath);
                    return false;
                }

                // Wait for the lock to be released
                System.Threading.Thread.Sleep(500);
            }
        }

        Log.LogTrace("WaitForFile {0} returning true after {1} tries",
            fullPath, numTries);
        return true;
    }

Очевидно, можно настроить тайм-ауты и повторения для удовлетворения приложению. Я использую это для обработки огромных файлов FTP, которые требуют времени, чтобы быть записанными.

6
ответ дан 10 December 2019 в 02:56
поделиться

Вы могли, возможно, создать файл с временным именем ("данные xml_TMP"), и когда это - готовое изменение имя к тому, что это, как предполагается. Тем путем никакой другой процесс не будет получать доступ к нему, прежде чем это будет готово.

1
ответ дан 10 December 2019 в 02:56
поделиться

Если Вы соединяете объект, хранивший как помехи затем, блокировка должна работать на все потоки в том же Домене приложения, но возможно необходимо загрузить пример кода, таким образом, мы можем взглянуть на незаконные строки.

Тем не менее одна мысль состояла бы в том, чтобы проверить, настроен ли IIS для выполнения в режиме Web Garden (т.е. больше чем 1 процесс, выполняющий приложение), который повредил бы логику блокировки. В то время как Вы могли зафиксировать такую ситуацию со взаимным исключением, будет легче реконфигурировать Ваше приложение для выполнения в единственном процессе, хотя Вы были бы мудры проверить производительность прежде и после питания с веб-настройками сада, поскольку это может потенциально влиять на производительность.

1
ответ дан 10 December 2019 в 02:56
поделиться

Хорошо, я работал над этим и закончил тем, что создал модуль стресс-теста, чтобы в основном ковать дерьмо из моего кода от нескольких потоков (См. Связанный Вопрос).

Было намного легче с этого момента найти дыры в моем коде. Оказывается, что мой код не был на самом деле далек, но был определенный логический путь, в который это могло войти, к которым в основном вызванным операциям чтения-записи сложить, имея в виду если бы они не стали очищенными вовремя, то это пошло бы бум!

После того как я вынул это, выполнил мой стресс-тест снова, все хорошо работали!

Так, я действительно не сделал ничего специального в своем коде доступа к файлу, просто гарантировал, что я использовал lock операторы в соответствующих случаях (т.е. при чтении или записи).

1
ответ дан 10 December 2019 в 02:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: