ColdFusion производительность и оптимизация блокировки - PullRequest
2 голосов
/ 09 марта 2012

У меня есть ссылка, по которой пользователи могут щелкнуть ее, и она получает файл фотографий в формате zip. Если zip-файл не существует, он запускает поток для создания zip-файла и отображает пользователю сообщение о том, что фотографии в настоящее время обрабатываются.

Чего я пытаюсь избежать, так это того, что пользователь несколько раз щелкает ссылку и выделяет целую массу потоков, которые попытаются создать / обновить zip-файл. Обработка zip-файлов требует значительных системных ресурсов, поэтому я хочу разрешить приложению генерировать только один zip-файл за раз. Если кто-то занят компилированием, он ничего не должен делать и ставить запросы в очередь.

В настоящее время я обращаюсь с этим с помощью cflock вокруг потока:

<cflock name="createAlbumZip" type="exclusive" timeout="30" throwontimeout="no">
  <cfthread action="run" albumId="#arguments.albumId#" name="#CreateUUID()#">
    ....

Я надеюсь, что здесь произойдет (кажется, что это работает, если я протестирую это), что он проверит, запущен ли в данный момент поток, использующий блокировку с именем 'createAlbumZip'. Если есть, он будет помещать запрос в очередь на 30 секунд, после чего он должен завершиться безо всякой ошибки. Если он не смог создать его в течение 30 секунд, это нормально.

Итак - похоже, это работает, но мой вопрос: это лучший способ справиться со сценарием, подобным этому? Является ли блокировка правильным подходом? Есть ли какие-либо недостатки, которые могут возникнуть из-за этого подхода, которого я не вижу?

Ответы [ 2 ]

2 голосов
/ 09 марта 2012

Есть миллион способов снять шкуру с этой кошки.Блокировка - это хорошее начало, и, согласно вашему комментарию к ответу @Pat Branley, я думаю, что ваша блокировка вне создания потока может быть немного более эффективной по той причине, которую вы предлагаете: существует потенциал для создания десятков потоков, весь срок жизни которыхбудет состоять из ожидания открытия блокировки или тайм-аута.

Еще одна вещь, которую вам нужно сделать, это удвоить выражение IF:

<cfif not (zip file exists)>
  <cflock ...>
    <cfif not (zip file exists)>
      <cfthread>
        ...create zip...
      </cfthread>
    </cfif>
  </cflock>
</cfif>

Это предотвратит случай, когда поток Bожидает, пока поток A создаст zip, а затем поток A завершит работу, а поток B продолжит воссоздание / перезапись его.

Кроме того, вы можете рассмотреть что-то вроде использования JavaScript для предотвращения лишних кликов, отключив кнопку /ссылка после щелчка.

0 голосов
/ 09 марта 2012

Я думаю, у вас неправильный код. Вы говорите: «Только одному потоку разрешено создавать этот новый поток». Теперь это может работать в вашем случае, потому что у вас установлены таймауты, так что никто не может создать другой поток, поэтому нет никакой вероятности, что два потока будут выполняться одновременно.

что вы хотите сказать, это "только один поток может сделать zip". Так что я бы сделал это

<cfthread .... >
  <cflock>
   ...zip....
...