{"action":"created","issue":{"url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/15671","repository_url":"https://api.github.com/repos/TrinityCore/TrinityCore","labels_url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/15671/labels{/name}","comments_url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/15671/comments","events_url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/15671/events","html_url":"https://github.com/TrinityCore/TrinityCore/pull/15671","id":110075104,"number":15671,"title":"[WIP] Dynamic script hotswapping","user":{"login":"Naios","id":1146834,"avatar_url":"https://avatars.githubusercontent.com/u/1146834?v=3","gravatar_id":"","url":"https://api.github.com/users/Naios","html_url":"https://github.com/Naios","followers_url":"https://api.github.com/users/Naios/followers","following_url":"https://api.github.com/users/Naios/following{/other_user}","gists_url":"https://api.github.com/users/Naios/gists{/gist_id}","starred_url":"https://api.github.com/users/Naios/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Naios/subscriptions","organizations_url":"https://api.github.com/users/Naios/orgs","repos_url":"https://api.github.com/users/Naios/repos","events_url":"https://api.github.com/users/Naios/events{/privacy}","received_events_url":"https://api.github.com/users/Naios/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/TrinityCore/TrinityCore/labels/Branch-6.x","name":"Branch-6.x","color":"188846"},{"url":"https://api.github.com/repos/TrinityCore/TrinityCore/labels/Comp-C++Script","name":"Comp-C++Script","color":"FF6600"},{"url":"https://api.github.com/repos/TrinityCore/TrinityCore/labels/Comp-Core","name":"Comp-Core","color":"FF6600"},{"url":"https://api.github.com/repos/TrinityCore/TrinityCore/labels/Priority-FutureFeatureRequest","name":"Priority-FutureFeatureRequest","color":"e102d8"}],"state":"open","locked":false,"assignee":{"login":"Naios","id":1146834,"avatar_url":"https://avatars.githubusercontent.com/u/1146834?v=3","gravatar_id":"","url":"https://api.github.com/users/Naios","html_url":"https://github.com/Naios","followers_url":"https://api.github.com/users/Naios/followers","following_url":"https://api.github.com/users/Naios/following{/other_user}","gists_url":"https://api.github.com/users/Naios/gists{/gist_id}","starred_url":"https://api.github.com/users/Naios/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Naios/subscriptions","organizations_url":"https://api.github.com/users/Naios/orgs","repos_url":"https://api.github.com/users/Naios/repos","events_url":"https://api.github.com/users/Naios/events{/privacy}","received_events_url":"https://api.github.com/users/Naios/received_events","type":"User","site_admin":false},"milestone":null,"comments":59,"created_at":"2015-10-06T18:49:24Z","updated_at":"2016-04-07T16:16:07Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/TrinityCore/TrinityCore/pulls/15671","html_url":"https://github.com/TrinityCore/TrinityCore/pull/15671","diff_url":"https://github.com/TrinityCore/TrinityCore/pull/15671.diff","patch_url":"https://github.com/TrinityCore/TrinityCore/pull/15671.patch"},"body":"## [WIP] Hotswap - Dynamic script hotswapping\r\n\r\n> \"Trinity should consider something like a C++ Engine...\"\r\n\r\n:white_check_mark: Mission success ...\r\n\r\n****\r\n\r\n6.x: [![Build Status](https://travis-ci.org/Naios/TrinityCore.svg?branch=hotswap)](https://travis-ci.org/Naios/TrinityCore) 3.3.5: [![Build Status](https://travis-ci.org/Naios/TrinityCore.svg?branch=hotswap_335)](https://travis-ci.org/Naios/TrinityCore)\r\n\r\n**[The 3.3.5 version is available now!](https://github.com/Naios/TrinityCore/commits/hotswap_335)**\r\n\r\n\r\n****\r\n\r\n![output_zw3zhg](https://cloud.githubusercontent.com/assets/1146834/10318227/bd2e2fa6-6c68-11e5-94f8-3aeaaf08d381.gif)\r\n\r\n****\r\n\r\n**Recompiles on script changes:**\r\n![savetocompile](https://github-cloud.s3.amazonaws.com/assets/1146834/10565274/267535d2-75cd-11e5-8342-cf0dc8b7e042.gif)\r\n\r\n\r\n****\r\n\r\n**Dynamic loaded modules based on source changes:**\r\n![preview2](https://cloud.githubusercontent.com/assets/1146834/10715842/e389d068-7b24-11e5-8f9a-4945d8a97938.gif)\r\n\r\n****\r\n\r\n**Reloadable command scripts based on file notifier (watches the linked `.dll` for changes):**\r\n![reload_commands](https://cloud.githubusercontent.com/assets/1146834/11120204/8b683978-894e-11e5-9392-45d0525c6939.gif)\r\n\r\n****\r\n\r\n**Demo video on Youtube:**\r\n\r\n[![Demo video](https://cloud.githubusercontent.com/assets/1146834/11341744/295fcd36-9204-11e5-9d85-56b57cdb7dad.png)](https://www.youtube.com/watch?v=y2sRbcCWMH4)\r\n\r\n---\r\n\r\n\r\n### Roadmap\r\n- [x] Readd \"missing script counter\"\r\n- [x] Auto-Configure compilation mode (Debug/Release)\r\n- [x] Clear outdated script.dll's from the script directory\r\n- [x] Route compiler output to TC logger.\r\n- [x] Detect binary incompatibility (**Partial:** warns about mismatching revision hashes)\r\n- [x] Fix script counter\r\n- [x] Fix install prefix correction in build tree\r\n- [x] Fix reloading of ScriptReloadMgr config\r\n- [x] Auto rerun CMake when sources are added/removed\r\n- [x] Check scheduled scripts\r\n- [x] Distinguish between default scripts and \"script\" scripts to replace default scripts when core scripts are loaded.\r\n- [x] Make `static std::unique_ptr<std::vector<ChatCommand>> commandTableCache` exchange atomic\r\n- [x] Check script load order (strange warnings) **-> not reproduceable on 3.3.5**\r\n- [x] Readd f809e5e13eac66add49d36\r\n- [x] Fix crash on shutdown\r\n- [x] Handle `Unit::i_disabledAI` (charms)\r\n- [x] Reinject all AI's before calling Reset\r\n- [ ] Remove the test stuff\r\n\r\n### Summary\r\n\r\nThis PR is splitted into multiple commits which cover:\r\n\r\n- **[:white_check_mark: merged]** **Transformation of the sub libraries to shared libraries** to expose singletons to shared libraries.\r\n  - It's still possible and recommended to link the server through full static linking (~20MB size .exe) except for developing purposes.\r\n  - Shared linking is enabled when `DYNAMIC_LINKING=1` in CMake is set or if a script is dynamic linked.\r\n  - The main disadvantage is that `TRINITY_*_API` macros needs to be added to all public interfaces.\r\n  - The travis build tests the full shared linkage to check for missing `TRINITY_*_API` macros.\r\n  - Singleton `instance()` methods were moved into the .cpp files to prevent duplicated instantiations of singletons on unix.\r\n- **[:clock4: outstanding]** **Splitting the scripts into independent modules**.\r\n  - Makes it possible to select the linkage (`disabled`, `static`, `dynamic`) for each module.\r\n    - Scripts marked as `disabled` are excluded from the build.\r\n    - Scripts marked as `static` are statically linked into the worldserver (instead of the game library which caused circular dependencies)\r\n    - Scripts marked as `dynamic` are linked into seperate shared libraries (\".dll's\", \".so's\") - one for each script subdirectory.\r\n  - **[:white_check_mark: merged]** The scriptloaders were splitted and are smaller now.\r\n  - **[:clock4: outstanding]**: The CMake `SCRIPTS` variable is responsible for the default linkage now.\r\n    - `SCRIPTS=\"none\"`: Disable all scripts\r\n    - `SCRIPTS=\"static\"`: Link all scripts statically (old `SCRIPTS=1` option)\r\n    - `SCRIPTS=\"dynamic\"`: Link all scripts dynamically\r\n    - `SCRIPTS=\"minimal-static\"`: Link the command and spell scripts statically (old `SCRIPTS=0` option)\r\n    - `SCRIPTS=\"minimal-dynamic\"`: Link the command and spell scripts dynamically\r\n- **[:clock4: outstanding]** **Adding the HotSwap main system which reloads script libraries on changes**.\r\n   - The ScriptReloadMgr is responsible for unloading/reloading shared libraries, just copy your .dll's or .so's to the scripts directory or delete it, **the worldserver will load/unload it immediatly**.\r\n   - The reloader is also capable to **invoke a build on filechanges**, just set the `HotSwap.EnableReCompiler` worldserver.conf option.\r\n   - Scripts can strong reference it's module to prevent it from unloading (useful for spells), which means **multiple versions of a script can be loaded at the same time** -> **Support for lazy unloading**.\r\n   - The ScriptMgr was rewritten entirely to support database bound and unbound storage layout for better performance.\r\n\r\n\r\n### Tutorial\r\n\r\n```sh\r\n# Add my fork to your repository\r\ngit remote add naios https://github.com/Naios/TrinityCore.git\r\ngit fetch naios\r\ngit checkout hotswap\r\n# or \"git checkout hotswap_335\" for the 3.3.5 version\r\n\r\n# Keep your local copy up to date\r\ngit fetch naios\r\ngit reset --hard naios/hotswap\r\n# or \"git reset --hard naios/hotswap_335\" for the 3.3.5 version\r\n\r\n# Use dynamic linking\r\n# Windows:\r\n# Set the `SCRIPTS` option in the cmake gui to \"dynamic\" or \"minimal-dynamic\"\r\n\r\n# Unix:\r\nmkdir build\r\ncd build\r\ncmake .. -DUSE_COREPCH=1 -DUSE_SCRIPTPCH=1 -DSCRIPTS=\"dynamic\" -DSERVERS=1 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install_dir\r\n#                                           ^^^^^^^^^^^^^^^^^^^^\r\n\r\nmake -j4\r\nmake install\r\n```\r\n\r\nIt's important to set the `CMAKE_INSTALL_PREFIX` to the location where you want to install the worldserver (even on windows!).\r\nUse the **INSTALL** target in Visual Studio!\r\n\r\nTo build script projects as modules you need to set it's linking option to `dynamic`.\r\nIt's recommended to disable some script modules for testing (because the solution will build faster).\r\nTest sources are located in the latest commit which provides a small testing environment at the gmisland.\r\n\r\nDon't forget to check out the `HotSwap.EnableReCompiler` worldserver.conf option to reload a script immediatly on a change.\r\n\r\n**Reviews, suggestions, criticism, testing and corrections are wished.**"},"comment":{"url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/comments/206976466","html_url":"https://github.com/TrinityCore/TrinityCore/pull/15671#issuecomment-206976466","issue_url":"https://api.github.com/repos/TrinityCore/TrinityCore/issues/15671","id":206976466,"user":{"login":"Naios","id":1146834,"avatar_url":"https://avatars.githubusercontent.com/u/1146834?v=3","gravatar_id":"","url":"https://api.github.com/users/Naios","html_url":"https://github.com/Naios","followers_url":"https://api.github.com/users/Naios/followers","following_url":"https://api.github.com/users/Naios/following{/other_user}","gists_url":"https://api.github.com/users/Naios/gists{/gist_id}","starred_url":"https://api.github.com/users/Naios/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Naios/subscriptions","organizations_url":"https://api.github.com/users/Naios/orgs","repos_url":"https://api.github.com/users/Naios/repos","events_url":"https://api.github.com/users/Naios/events{/privacy}","received_events_url":"https://api.github.com/users/Naios/received_events","type":"User","site_admin":false},"created_at":"2016-04-07T16:16:07Z","updated_at":"2016-04-07T16:16:07Z","body":"Just a quick note about the current state of development:\r\nIn the last 2 weeks I implemented some missing features like (auto cmake rerun when files are added or removed) and fixed various issues:\r\n\r\n- The script reloader is fully asynchronous, atomic and nonblocking now -> doesn't affect the difftime anymore (through blocking while waiting for external processes)\r\n- Fixed multiple crashes caused by scripts in instances when the script library is removed (it's possible to remove the library while being infight now -> thanks to lazy unloading and the worldserver which inject sdefault AI's then).\r\n- Major code improvements, and minor improvements\r\n\r\nAll in all this PR seems to be very stable for me which means **I finally plan to merge it on monday into both branches**..\r\n\r\nLet me know when you find any bugs meanwhile."}}