|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Привет, холливарщикам! Хорош сраться, лучше помогите мне придумать очередной велосипед WARNING: Весь код условный, на компилирование и эстетическую красоту не претендующий, мне главное - донести идею и проблему показать. Предположим есть некий класс а ля type erasure функтор class Action Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
есть RAII обертка для массива объектов Action, которая при своем разрушении вызывает каждую из добавленных в него Action в обратном порядке class UndoActions Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30.
Смысл я думаю понятен. Мы можем добавлять в UndoAction функции и их аргументы, которые будут вызваны в момент разрушения экземпляра класса UndoActions автоматически. Мне это понадобилось, потому что есть потребность отрефакторить несколько сложных функций портянок. Они уже оптимизированы и во всю используют ООП, но все равно из-за своей сложности остаются большими и неудобными к дальнейшей доработке. Поскольку выполняемые в них действия связаны с важными ресурсами, засирать которые обломками неудачных попыток нежелательно, я решил придумать такой вот UndoActions откатчик действий, работающий сугубо на стеке, поэтому вполне способный обходится локальными данными (raw указателями на данные или ссылками), которыми оперирует сама функция-носитель. По задумке работать это должно вот так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36.
Проблему я думаю уже все заметили - и имя ей - порядок освобождения объектов на стеке. Он LIFO, а значит, когда UndoActions соберется делать Rollback в деструкторе, все объекты string уже будут удалены, следовательно ничего оно почистить не сможет! Если вообще не крашанется... Вытаскивать все string (в реальном коде там другие, более сложные RAII объекты) наверх до undo как-то по ламерски и не комильфо. Можно было бы сделать shared-типы из аргументов, но тогда будут проблемы с сигнатурами функций у функтора (он не сможет их нормально сопоставить с undo-функциями, так как они ожидают другие типы, а у компилятора шаблоны, type safety, да и как потом их чистить, функтор Action тоже про это ничего не знает). Попробовал было __try / __finally, но был послан из-за unwinded Может есть способ сказать компилятору, чтобы он разрушал undo раньше всех остальных или есть какие-то другие мысли, как сделать это корректно? Если что я на MSVC2017 Cx17, поэтому все сопутствующие non standard фичи под Windows могу смело юзать. -------------------------------------------------------------- o(O_O)o ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 15:37 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Cerebrum, Так передавайте строки по значению, а не c_str() ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 15:46 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Anatoly Moskovsky, сигнатуры RemoveDirectory/RemoveFile/DestroyDatabase не знают что такое string, они знают только char*/wchar_t* поэтому компилятор тупо не сможет сопоставить функцию в Action по переданным string параметрам. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 15:57 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
CerebrumAnatoly Moskovsky, сигнатуры RemoveDirectory/RemoveFile/DestroyDatabase не знают что такое string, они знают только char*/wchar_t* поэтому компилятор тупо не сможет сопоставить функцию в Action по переданным string параметрам.тупую обёртку написать RemoveDirectory( std::string path ) { return RemoveDirectory( paht.c_str() ); }? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 16:03 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Cerebrum, Может, стоило бы реализовать паттерн Команда (даже в функциональном стиле, на лямбдах), чтобы все данные для do и undo принадлежали одной и той сущности? А то ты хочешь сразу на двух стульях сидеть, и писать plain код как есть и заодно stack unwinding перехитрить. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 16:04 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
egorychCerebrumAnatoly Moskovsky, сигнатуры RemoveDirectory/RemoveFile/DestroyDatabase не знают что такое string, они знают только char*/wchar_t* поэтому компилятор тупо не сможет сопоставить функцию в Action по переданным string параметрам.тупую обёртку написать RemoveDirectory( std::string path ) { return RemoveDirectory( paht.c_str() ); }? да, можно попробовать спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 16:08 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
egorychтупую обёртку написать RemoveDirectory( std::string path ) { return RemoveDirectory( paht.c_str() ); }? Не обязательно обертки писать для функций. Достаточно написать обертку для строки с оператором приведения к const char* ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 16:11 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
NekZCerebrum, Может, стоило бы реализовать паттерн Команда (даже в функциональном стиле, на лямбдах), чтобы все данные для do и undo принадлежали одной и той сущности? А то ты хочешь сразу на двух стульях сидеть, и писать plain код как есть и заодно stack unwinding перехитрить. тоже думал о подобном, чтобы команда в случае неудачи все отменяла, но если комада отработала нормально, а следующая нет, то как предыдущая узнает что ей надо делать откат? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 16:11 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Anatoly Moskovskyegorychтупую обёртку написать RemoveDirectory( std::string path ) { return RemoveDirectory( paht.c_str() ); }? Не обязательно обертки писать для функций. Достаточно написать обертку для строки с оператором приведения к const char* другими словами, без еще одной копии данных принадлежащей строго Action не получается ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 16:15 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
CerebrumNekZCerebrum, Может, стоило бы реализовать паттерн Команда (даже в функциональном стиле, на лямбдах), чтобы все данные для do и undo принадлежали одной и той сущности? А то ты хочешь сразу на двух стульях сидеть, и писать plain код как есть и заодно stack unwinding перехитрить. тоже думал о подобном, чтобы команда в случае неудачи все отменяла, но если комада отработала нормально, а следующая нет, то как предыдущая узнает что ей надо делать откат? Сделай класс макро-команды, которая просто набивает в очередь команды и последовательно их выполняет, перекладывая в стек (структуру данных) выполненных. В случае облома, все выполненные из стека выталкиваются и undo-ятся. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 16:28 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Anatoly MoskovskyНе обязательно обертки писать для функций. Достаточно написать обертку для строки с оператором приведения к const char*и впрямь)) но это уже не тупая, это подумать пришлось)) ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 16:50 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Cerebrum, Кстати, можно было бы провернуть трюк goto-без-goto Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 17:29 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
1) Выкидываешь Action, берёшь std::function 2) В UndoActions переделываешь Add чтобы он принимал только F, при вызове суёшь лямбду, в которой захватываешь всё что нужно по значению 3) Выкидываешь UndoActions и переезжаешь на Boost.ScopeExit или на folly scopeguard или на что-нибудь подобное. Минусы: придётся руками везде проверять условие выхода. Плюсы: нет проблем с порядком разрушения, естественная структура данных для хранения действий отката. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 17:32 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
egorychAnatoly MoskovskyНе обязательно обертки писать для функций. Достаточно написать обертку для строки с оператором приведения к const char*и впрямь)) но это уже не тупая, это подумать пришлось)) пробовал по всякому Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66.
авторerror C2664: 'FuncCaller<BOOL (__stdcall *)(LPCWSTR),TypeWrapper>::FuncCaller(const FuncCaller<BOOL (__stdcall *)(LPCWSTR),TypeWrapper> &)': cannot convert argument 2 from 'TypeWrapper' to 'TypeWrapper &&' note: You cannot bind an lvalue to an rvalue reference ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 17:57 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Я вижу у тебя только операции над файлами. В этом случае транзакции тебе помогут: https://docs.microsoft.com/en-us/windows/desktop/fileio/about-transactional-ntfs https://docs.microsoft.com/en-us/windows/desktop/fileio/deprecation-of-txf https://stackoverflow.com/questions/17593233/what-are-transactional-file-operations Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 18:06 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Cerebrumпробовал по всякомучто то как то сложно)) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21.
P.S. не компилировал ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 18:10 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
egorych, Всё равно error-prone code. Забудешь написать undo.Add где-нибудь и усё :) ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 18:12 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Dimitry SibiryakovЯ вижу у тебя только операции над файлами. В этом случае транзакции тебе помогут: https://docs.microsoft.com/en-us/windows/desktop/fileio/about-transactional-ntfs Сам-то читал что по ссылке? Microsoft strongly recommends developers utilize alternative means to achieve your applications needs. Many scenarios that TxF was developed for can be achieved through simpler and more readily available techniques. Furthermore, TxF may not be available in future versions of Microsoft Windows. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 18:14 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
NekZegorych, Всё равно error-prone code. Забудешь написать undo.Add где-нибудь и усё :)это же не промышленный код, вроде. для тестирования и рефакторинга сойдёт, кмк. P.S. я бы, кстати, вместо Add сделал бы оператор << ))) ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 18:16 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Dimitry SibiryakovЯ вижу у тебя только операции над файлами. В этом случае транзакции тебе помогут: https://docs.microsoft.com/en-us/windows/desktop/fileio/about-transactional-ntfs https://docs.microsoft.com/en-us/windows/desktop/fileio/deprecation-of-txf https://stackoverflow.com/questions/17593233/what-are-transactional-file-operations я для примера привел, чтобы народу мозг не забивать всякой работой с доменом и прочими БД, ну и файловые операции там тоже есть ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 18:18 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
a.guestСам-то читал что по ссылке? А что тебя особо пугает в "используйте технологии, соответствующие нуждам вашего приложения"? То, что кроме первой ссылки придётся прочитать ещё две?.. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 18:20 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Dimitry SibiryakovА что тебя особо пугает в "используйте технологии, соответствующие нуждам вашего приложения"?Нужнам каких приложений соответствуют deprecated технологии? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 18:25 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
Cerebrum, В данном варианте в случае ошибки просто убиваешь папку со всем содержимым. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 18:25 |
|
Автоматический откат действий
|
|||
---|---|---|---|
#18+
blonduserв случае ошибки просто убиваешь папкуБедный папка, его-то за что? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2018, 18:27 |
|
|
start [/forum/topic.php?fid=57&msg=39752895&tid=2017695]: |
0ms |
get settings: |
9ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
27ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
54ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 137ms |
0 / 0 |