Bukkit/Spigot - How to wait until BukkitRunnable is finished - multithreading

In my onDisbale() method in my Main class I have a loop which creates and starts new BukkitRunnables.
I'm getting a error in console: org.bukkit.plugin.IllegalPluginAccessException: Plugin attempted to register task while disabled I need to somehow wait in my onDisable() method until all the BukkitRunnables I create in the loop are finished. How to do that?
My code looks like this:
#Override
public void onDisable() {
for (Player p : Bukkit.getOnlinePlayers()) {
new PlayerDataSaverRunnable().runTaskAsynchronously(this);
}
}

The onDisable method is the very last thing that gets called before your plugin is disabled and the server shuts down. So, as the error message says, you unfortunately can't schedule any new tasks in the onDisable function.
You mentioned in a comment that you were trying to write to a file in the plugins folder, and under normal circumstances you'd want to do that asynchronously. But, because onDisable only ever gets called when the server is shut down (or when the entire server is reloaded with /reload), it's perfectly fine to run code here that blocks the main thread and could potentially take a few seconds to run — in the case of a shutdown, by the time this method gets called, all the players will have already been kicked off the server, and so there's no "lag" to complain about. If your plugin is super advanced and has to save a bunch of stuff, I don't think any server owners would complain even if it took 10 or so seconds to disable.
Of course, you would have to be saving something crazy for it to take a whole 10 seconds to save. More than likely, most files will save in just a few milliseconds.
If you're really dead-set on disabling the plugin as fast as possible, you might consider having some async task that runs every 5 minutes or so and auto-saves the files. Then, in onDisable, you could only save files that changed since the auto-saver was last run. That's a good practice anyways, just incase the server crashes or the power goes out and the onDisable method doesn't get a chance to run. But, then again, I would still recommend that you save everything in the onDisable method (that's what I do for all of my plugins, as well), even if it will take a few seconds and block the main thread, just so you can be 100% sure that everything gets saved correctly.

Related

What is Comunication Failure in Shopware 5?

when creating new theme there's error occurred.
0 - Communication Failure
Why this happen? could you please help me?
This usually happens due to a timeout that occurs when the Theme-controller tries to read the Theme's configuration for the first time. Unfortunately, this is quite a resource-heavy process; on weaker servers, timeouts may occur during this process quite often.
You can confirm this by opening the Theme-Manager, opening your browser's developer tools, refreshing the Theme overview and look at the response of the backend/Themes/list-Request.
You can give your server more time with the php-function set_time_limit. In engine/Shopware/Components/Theme/Installer.php, in the synchronize-method, prepend set_time_limit(0):
public function synchronize()
{
set_time_limit(0);
$this->synchronizeThemes();
}
Alternatively, prepend set_time_limit(0); to your shopware.php file, but don't forget to remove it again once the theme-overview loaded successfully.

SailJs is Deleting Data from pg database

Something strange is happening with my app, I am using SailsJs with official PostgreSQL driver and my data gets deleted. I don't have any pattern or list of specific events which deletes the data but I have following observations.
Few days back i was writing a function to destroy data and when I
executed that function it gave me an error I fixed the error and ran
my web app again and whoa data from one of my table was all gone.
Yesterday i wrote a function and I tried to get the HTTP call to that
function but it was giving me 500 server error, I started debugging it
and after executing my program 3 to 4 times with this error partial
data was deleted from one of my database table. Later the error was i
had a typo in URL.
If any of you guys had any experience with what is happening to me please let me know how to fix it? or at least help me on how to reproduce this issue ?
EDIT
I activated the logs and was waiting for it to happen again and it happened again and here is the log from sailsjs
In the logs I saw that its talking about alter.js sync strategy but i have selected it to be the safe strategy
It has happened to me quite a few times, when lifting the app and it is in the process of making changes to the db and it fails, sometimes due to ORM timeout.
What sails do when its lifting and needs to update the data structure is controlled in config/models.js migrate: 'alter', usually commented out, you get a prompt for what to do 1... 2... 3... (writing from the top of my head, i dont remember the actual messages) and a warning about using alter on a production system.
Changing
config/orm.js to have this
// config/orm.js
module.exports.orm = {
_hookTimeout: 60000 // I used 60 seconds as my new timeout
};
And for reasons I don't know changing config/pubsub.js
// config/pubsub.js
module.exports.pubsub = {
_hookTimeout: 60000 // I used 60 seconds as my new timeout
};
has helped me, avoid data loss.

hunchentoot-based app in a lisp image (from buildapp) immediately returns

So I have an application using restas, based on hunchentoot.
At some point, I have the following function:
(defun main (args)
(declare (ignore args))
(set-config)
(restas:start '#:spa :port 8080))
(set-config) sets a few values related to database.
Anyway, I then use buildapp in the following way:
buildapp --output dist/spa --load-system spa --asdf-tree ~/quicklisp/ --entry spa::main --compress-core
Which works perfectly. The (set-config) function requires a config.json file to be present, and it indeed doesn't work when the file doesn't exist, so I know for sure that the application is correctly compiled.
When I run the generated binary however, the application immediately returns. Which means the HTTP server doesn't stay up.
I guess it's related to the fact that hunchentoot spawns a new thread, but it shouldn't stop the process, should it?
Also, I don't want to not use threads, i.e. I want the fact that each request is a separate thread.
So... I'm not sure exactly why it immediately returns. Why? And how to fix it?
I guess that you have to enter a main loop to keep the program running. The example at http://www.xach.com/lisp/buildapp/ uses the SBCL-specific (sb-impl::toplevel-repl nil).

libspotify: logging out or releasing session causes crash

This is in response to dan's (dan^spotify on IRC) offer to take a look at my testcase, but I post it here in case anyone has encountered similar issues.
I'm experiencing a problem with libspotify where the application crashes (memory access violation) in both of these two scenarios:
the first sp_session_process_events (triggered by notify main thread callback) that's called after the sp_session_logout() function is called crashes the application
skipping logout and calling sp_session_release() crashes the application
I've applied sufficient synchronization from the session callbacks, and I'm otherwise operating on a single thread.
I've made a small testcase that does the following:
Creates session
Logs in
Waits 10 seconds
Attempts to logout, upon which it crashes (when calling sp_session_process_events())
If it were successful in logging out (which it isn't), would call sp_session_release()
I made a Gist for the testcase. It can be found here: https://gist.github.com/4496396
The test case is made using Qt (which is what I'm using for my project), so you'd need Qt 5 to compile it. I've also only written it with Windows and Linux in mind (don't have Mac). Assuming you have Qt 5 and Qt Creator installed, the instructions are as follows:
Download the gist
Copy the libspotify folder into the same folder as the .pro file
Copy your appkey.c file into the same folder
Edit main.cpp to login with your username and password
Edit line 38-39 in sessiontest.cpp and set the cache and settings path to your liking
Open up the .pro file and run from Qt Creator
I'd be very grateful if someone could tell me what I'm doing wrong, as I've spent so many hours trying anything I could think of or just staring at it, and I fear I've gone blind to my own mistakes by now.
I've tested it on both Windows 7 and Linux Ubuntu 12.10, and I've found some difference in behavior:
On Windows, the testcase crashes invariably regardless of settings and cache paths.
On Linux, if setting settings and cache to "" (empty string), logging out and releasing the session works fine.
On Linux, if paths are anything else, the first run (when folder does not already exist) logs out and releases session as it should, but on the next run (when folder already exists), it crashes in the exact same way as it does on Windows.
Also, I can report that sp_session_flush_caches() does not cause a crash.
EDIT: Also, hugo___ on IRC was kind enough to test it on OSX for me. He reported no crashes despite running the application several times in a row.
While you very well may be looking at a bug in libspotify, I'd like to point out a possibly redundant call to sp_session_process_events(), from what I gathered from looking at your code.
void SessionTest::processSpotifyEvents()
{
if (m_session == 0)
{
qDebug() << "Process: No session.";
return;
}
int interval = 0;
sp_session_process_events(m_session, &interval);
qDebug() << interval;
m_timerId = startTimer(interval);
}
It seems this code will pickup the interval value and start a timer on that to trigger a subsequent call to event(). However, this code will also call startTimer when interval is 0, which is strictly not necessary, or rather means that the app can go about doing other stuff until it gets a notify_main_thread callback. The docs on startTimer says "If interval is 0, then the timer event occurs once every time there are no more window system events to process.". I'm not sure what that means exactly but it seems like it can produce at least one redundant call to sp_session_process_events().
http://qt-project.org/doc/qt-4.8/qobject.html#startTimer
I notice that you will get a crash on sp_session_release if you have a track playing when you call it.
I have been chasing this issue today. Login/logout works just fine on Mac, but the issue was 100% repeatable as you described on Windows.
By registering empty callbacks for offline_status_updated and credentials_blob_updated, the crash went away. That was a pretty unsatisfying fix, and I wonder if any libspotify developers want to comment on it.
Callbacks registered in my app are:
logged_in
logged_out
notify_main_thread
log_message
offline_status_updated
credentials_blob_updated
I should explicitly point out that I did not try this on the code you supplied. It would be interesting to know if adding those two extra callbacks works for you. Note that the functions I supply do absolutely nothing. They just have to be there and be registered when you create the session.
Adding the following call in your "logged in" libspotify callback seems to fix this crash as detailed in this SO post:
sp_session_playlistcontainer(session);

Determine extension state

In my chrome extension I would like to make any changes in user preferences in-memory while the extension is running, and only save the preferences (as a JSON obj) to localStorage when the extension is about to terminate (I use a background html page in my extension).
I am currently writing to localStorage every time a preference is changed but am looking to see if this can be made more efficient to avoid writing to disk on each preference change and instead just do it once before termination.
Is there any way to know when the extension is being terminated or does anyone know of a better approach to handle this scenario?
Does this help?
function saveSettings(){
window.clearTimeout(window.savingSettings);
return window.savingSettings = window.setTimeout(function(){
... // write to local storage here.
},2000)
};
This will makes sure:
there's at least two seconds between save operations
the whole thing runs somewhat parallelized to the main thread
You should see a performance boost to some degree but there's a catch. If a user closes the browser without waiting those two seconds after changing a pref, prefs won't be saved.

Resources