Jump to content

Recommended Posts

Posted

Hi @adrian, often your actions turn out to be life saving! I've a similar request of Fuzen for the use a field type.

In the action "Field Set Or Search And Replace", 
it doesn't seem to be possible to manipulate a field type Options/Radios. Is this an unsupported field, or is it possible to extend the use to this fieldtype?
I think that would really be very helpful.

Thanks

Posted

@Mike-it - the latest version supports the Options field type but note that you need to use the numeric key for the option rather than the label, so 1 or 2 rather than Yes or No, for example.

  • Like 1
  • Thanks 1
  • 2 weeks later...
  • 1 month later...
Posted

Hi @adrian,

while your module is a real pleasure to work with, i wonder if i miss something, as "Copy Field Content to other Page" seems not to work with fields of type "files". The references are copied, but the files itself not.

Not sure if this is intended or maybe a bug?

Cheers
Olaf

  • Like 1
  • 6 months later...
Posted

Hi @adrian,

I have an action that was working in v0.9.8

<?php namespace ProcessWire;
class DownloadModulesDirectory extends ProcessAdminActions {
	protected $title = 'Download modules directory';
	protected $description = 'Download a ZIP file of /site/modules/';
	protected $author = 'Robin';
	protected $dbBackup = 'disabled';
	
	protected function defineOptions() {
		return array();
	}
	
	protected function executeAction($options) {
		$files = $this->wire('files');
		$config = $this->wire('config');

		$zip_pathname = $config->paths->site . 'modules.zip';
		$files->zip($zip_pathname, $config->paths->siteModules, ['overwrite' => true]);
		$files->send($zip_pathname);

		return true;
	}

}

In v1.0.1 the zip is created but a download isn't prompted, and I see this when executing the action:

image.png.9f812152b3b4132bf821587fa58b7e2a.png

 

  • Like 1
Posted

Sorry about that @Robin S - I had checked file downloads with the new version, but not using PW's $files->send.

I tested with your example above and it's working again in the latest version.

Please let me know if you notice any issues. I think it's really nice having actions run in the background now so that aren't subject to any time limits, but it has complicated things.

  • Like 4
Posted

Thanks @adrian, working great now.

6 hours ago, adrian said:

I think it's really nice having actions run in the background now so that aren't subject to any time limits

Yes, love this feature here, and in the Tracy Console too. Thanks for adding it!

  • Like 1
  • 2 months later...
Posted

Hi @adrian,

When I attempt to run the action mentioned here...

...I get the error:

{"error":true,"message":"Cannot access non-public member Tracy\\FileSession::$file"}

I have the latest versions of Admin Actions and Tracy installed.

  • Like 1
  • 3 months later...
Posted

Hi @adrian,

I'm experiencing an issue where data set to $session within executeAction() doesn't survive to the next request. I made this test action as a demo:

class TestSession extends ProcessAdminActions {

	protected $title = 'Test Session';

	protected function defineOptions() {
		$colour = $this->wire()->session->get('colour');
		bd($colour, "colour");
		return [];
	}

	protected function executeAction($options) {
		$this->wire()->session->set('colour', 'red');
		$test = $this->wire()->session->get('colour');
		bd($test, "test");
		return true;
	}

}

I can get the set colour in $test, but once I return to the action options screen (e.g. as if I was about to execute the action again) then $colour is null. Can you reproduce this at your end?

  • Like 1
Posted

Hey @Robin S - I hate what I have turned into 😁, but it should be fixed now - here is Claude's explanation:

Actions now run in the background via AJAX, so a long-running action can't hit a proxy or browser timeout. To stop the polling requests from being blocked by PHP's session lock, the module closed the session before calling executeAction(). Once the session is closed, PHP doesn't save anything else written to it. That's why you could read colour back straight away but it was gone on the next request.

In 1.0.9 the module takes a snapshot of the session before closing it. After the action finishes, it reopens the session and writes back only what the action added, changed or removed. Anything the polling requests changed in the meantime is left alone. This also works when the action ends with a file download.

Your TestSession action should now work as you expected. Let me know if it doesn't.

  • Like 1
Posted

Thanks @adrian, working now.

Something else: I had an issue where a particular host forces an HTTP connection time limit separate from the PHP time limit. So if an action ran for more than 120 seconds it would quit with a 503 error. I think this limit sucks but I can't convince them to change it. Do you (or your AI agent 😁) know if AdminActions could avoid such a connection time limit somehow? I'm not sure what wizardry you did to get actions to run in the background, but maybe it could somehow start a new request periodically? No worries if that's too tricky or impossible - I just thought I'd ask. 🙂

  • Like 1
Posted

Thanks @Robin S, glad the session fix is working.

About the 120-second limit: a long action already keeps running after the browser connection drops (the module calls `ignore_user_abort(true)`). The browser then switches to polling for the result. At the moment, though, it only does that when the request fails with no response or with a 502 or 504. A 503 is treated as a real error, so you get the error message even if PHP is still working away on the server.

Could you try a quick change in `ProcessAdminActions.js` at line 188? Change:

if(xhr.status === 502 || xhr.status === 504) {


to:

if(xhr.status === 502 || xhr.status === 503 || xhr.status === 504 || xhr.status === 524) {


Clear your browser cache, then run a long action. If the host only closes the connection and leaves PHP running, the status should switch to "Running in background…" after the 503 and show the result once the action finishes.

If it just spins and never finishes, the host is killing the PHP process too, not only the connection. Is that host running LiteSpeed? 120 seconds is LiteSpeed's default connection timeout. If it is, adding this near the top of your `.htaccess` (after `RewriteEngine On`) should tell it not to abort or time out PHP:

RewriteRule .* - [E=noabort:1,E=noconntimeout:1]


Let me know how it goes. If the JS change works, I'll add it to the next version.
 

  • Like 1
Posted

Thanks for the suggestions @adrian. The host is running LiteSpeed. I tried updating ProcessAdminActions.js and the addition to .htaccess (I also tried specifying the specific action php file) but the action execution still stopped after approximately 120 seconds.

My test action is:

protected function executeAction($options) {
	$config = $this->wire()->config;
	$files = $this->wire()->files;
	$filename = $config->paths->root . 'test.txt';
	for($i = 0; $i < 130; $i++) {
		sleep(1);
		$files->filePutContents($filename, "Iteration $i\n", FILE_APPEND);
	}
	return true;
}

After 120 seconds I saw this:

image.png.f59a3ccdc4d58ae17fffbd255b9df612.png

image.png.cc17c79360a9d896d864cf496f16ec46.png

And the contents of the text file ended at "Iteration 118".

I can run PHP scripts for longer via cron or the command line, but it's less user-friendly than AdminActions.

Seeing as my long-running actions are always looping over something my workaround is to break out of the loop when I'm approaching 120 seconds and store the iteration I'm up to in session. Then I run the action again to continue from where I was up to, and repeat as needed. Not ideal but it gets the job done. 

Posted

Hey @Robin S - thanks for trying that out.

Does Litespeed make exec() or proc_open() available? If so I might be able to push the action to run via CLI and avoid the time limit.

PS - can I assume you have the same issues with Tracy console's fairly recent background processing as well?

  • Like 1
Posted
32 minutes ago, adrian said:

Does Litespeed make exec() or proc_open() available?

Currently proc_open() is available and exec() is disabled, but I have the option to enable exec(). One of the things that makes AdminActions great is that I can dump objects and messages to myself via Tracy. Would that still be possible if the action is run via CLI?

33 minutes ago, adrian said:

can I assume you have the same issues with Tracy console's fairly recent background processing as well

Yes, I get the same 503 error with anything running longer than 2 minutes.

Don't spend much time on this unless you think it would be useful more broadly.

Posted

Hi @adrian,

On an unrelated note, I got this error message when executing an action:

image.png.3632815aa2a6774d690e00b3a6bc4441.png

It took me a while to track down the cause because nothing was recorded in the PW errors or exceptions logs. It turned out that the action code accidentally included db() when what I intended to type was bdb(). Is there a way that action errors like this could be picked up by the Tracy error handler, or some more information about the error could be shown in the error message? 

Posted

Hi @Robin S — thanks for the details. AdminActions 1.1.0 and TracyDebugger 5.1.9 should take care of all three things.

The 2-minute limit: there's a new Execution mode setting in the AdminActions module config. Set it to CLI and each action is started in its own PHP CLI process, so LiteSpeed's 120s limit doesn't apply. It only needs proc_open(), so you don't need to enable exec(). The browser shows "Running in background…" and displays the result when it's done, and your actions don't need any changes. The PHP CLI binary is detected automatically. If detection picks the wrong one, set PHP CLI path. You can also set it per action with protected $executionMode = 'cli';.

Tracy dumps: yes, they still work in CLI mode. bd() / bdb() dumps are shown with the action's result (under "Tracy bar dumps") instead of in the bar, and d() / db() work as usual. That part needs the new TracyDebugger 5.1.9. The one thing CLI mode can't do is keep changes an action makes to $session, because there's no browser session in a CLI process.

There's also a batching option if you'd rather stay in the browser: check $this->timeUp() in your loop and return $this->continueWith(['i' => $i]); and the module runs the next batch in a fresh request automatically. That's your session workaround, built in. Details are in the README.

The db() error: db() is actually Tracy's "dump big" shortcut, so it ran fine. But it printed its output into the background-run response, which broke the result. That's why you got a meaningless error and nothing in the logs. Anything an action prints (echo, d(), db()) is now shown with the result. Real exceptions and PHP errors, like an undefined function, are now shown with the file and line, and logged to both the PW exceptions log and Tracy's log.

I'll look at a CLI option for the Tracy Console's long-running scripts next, since it has the same problem.

Let me know how it goes on that host!

  • Like 1
Posted

@Robin S — TracyDebugger 5.1.10 adds a Run in CLI checkbox to the Console for long scripts. It works the same way as AdminActions' CLI mode: bd() dumps are shown with the result, and Cancel and Stream results still work.

  • Like 3
Posted

Wow @adrian, that is amazing! It's working well with the test action at my problematic host, and I'm sure to have occasions to try it out with a real action soon. Fantastic having the CLI option in the Tracy console too. Thanks for finding these great solutions.

  • Like 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...