Seaside: CannotDeleteFileException: не удалось удалить старую версию топливного файла

В приложении pharo seaside при нажатии кнопки «Домой» все данные будут сохранены в топливном файле с некоторым именем класса как Test.fl. Если я вызываю одну и ту же домашнюю страницу одновременно в двух экземплярах, оба вызывают этот код ниже, чтобы сохранить файл Test.fl с последними обновлениями,

FLSerializer
    serialize: self allObjects
    toFileNamed: self name , '.fl'**

и получение исключения:

CannotDeleteFileException: не удалось удалить старую версию файла ...\Pharo3.0\Test.fl

И я использовал Mutex, чтобы разрешить выполнение другого экземпляра после первого экземпляра,

mutexBlock := Mutex new.
mutexBlock critical: [
    FLSerializer
        serialize: self allObjects
        toFileNamed: self name , '.fl' ]

Но все же я получаю ту же ошибку

CannotDeleteFileException: не удалось удалить старую версию файла

Пожалуйста, помогите мне в этом, чтобы исправить ошибку.


person Jayalakshmi Lade    schedule 16.05.2016    source источник


Ответы (2)


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

Тогда ваш код будет выглядеть примерно так:

MyClass class>>serializeProtect
    ^ SerializeProtect ifNil: [ SerializeProtect := Mutex new ]

self class serializeProtect critical: [
    FLSerializer
        serialize: self allObjects
        toFileNamed: self name , '.fl' ]

Примечание: обычно не лениво инициализировать Mutex. Я просто делаю это здесь для простоты.

person Max Leske    schedule 16.05.2016
comment
Это работает. Я взял переменную класса и инициализировал ее в методе инициализации класса. Спасибо, Макс. - person Jayalakshmi Lade; 18.05.2016
comment
Рад, что смог помочь. - person Max Leske; 18.05.2016

Вам не нужен мьютекс там. Seaside в Pharo обрабатывает запросы по одному. То есть это работает только в том случае, если ваша запись файла выполняется быстро, так как все остальные соединения ждут завершения записи. Если это не так, вам нужно будет писать в отдельном потоке, а затем действительно контролировать доступ к нему.

person Stephan Eggermont    schedule 28.05.2016