Getting non modx services

Hi, I developed a simple service class to interface with paypal, and triying to instantiate using $modx->getService like this:

$admUsrMgr = $modx->getService(
‘PayPalConnector’,
‘PayPalConnector’,
‘/html/modxMonster/plugins/’
);

But everytime the code execution gets to this place, the constructor is called again, doing some deeper debug, I find that when it gets into the method, it creates the class and stores it into the services array, but on later calls, the service instance is gone, what Im misggin? below some of my code.

Snippet:

require_once(dirname($modx->getOption(‘base_path’)).‘/html/modxMonster/plugins/reportChangesOnAdminUsers.php’);

PayPalConnector::loadService($modx);
return $modx->PayPalConnector->processEvent();

Relevant class code

public static function loadService($modx) {
// $corePath = $modx->getOption(‘modxMonster.core_path’);
$admUsrMgr = $modx->getService(
‘ReportChangesOnAdminUsers’,
‘ReportChangesOnAdminUsers’,
‘/html/modxMonster/plugins/’
);

if (!($admUsrMgr instanceof ReportChangesOnAdminUsers)){
  $modx->log(modX::LOG_LEVEL_ERROR, "Could not load AdminUserChangesSupervisor!!!!");
} 

}

The code itself works as expected, but I was wondering why the class instance isn’t kept and it worries me that it can lead to memory issues in the future.

If by “later calls” you mean in the same request, then that would be curious. If you mean on subsequent requests, then that is normal. PHP executes everything on each request. Nothing is kept in memory between requests. I’m not sure if that’s what you are worried about or not, but that is as expected.

1 Like

HI @opengeek thanks a lot for your response, Im kind of new in PHP and come from a java world, and what worries me is memory management/garbage collection, per design I usually put all “heavy” operations on the constructor so those are only executed once, and later I can access them for use, like the singleton on java spring, can you point me to any direction that explains how this works on PHP, and why it should not worry me?

Also when I debug the modX object, I see other services in the array between requests, like the lexicon among others, how can I achieve something similar? this question come from the fact that I use some components that has heavy loading times, and are used very often, and having the user waiting for those to initialize at every request would create a terrible UX

PHP and Java are very different programming languages. For one, Java is compiled while PHP is interpreted dynamically. PHP processes are typically short-lived and memory management/gc is not typically a userland consideration.

What components do you have that take a long time (= noticable to the user they are waiting for something) to load? A simple getService call should be < 1ms.

1 Like

Thanks for your response @markh, and i’m in the process of diving deep on the technicalities of PHP and undrstadning the differences.

Currently i’m working on a prototype that communicates with an external crappy old ESB that requires some time and steps the first time you establish the connection, and also has some constraints on how many new connections I can establish on a given time, and I need to interact with such system on different steps/requests along the user journey, and just creating the whole resource every time whould rendere the system almos unusable, maybe something like this could help?

Few thoughts/ideas…

  • If your initial setup/connection is related to setting up authentication and getting some sort of access token, you can save that access token somewhere (in a session, or a shared file cache) and access that more quickly on the next request. Implemented correctly, the second request should be much quicker.

  • It may also be interesting to break apart a user waiting on a response, and for the ESB to return the data requested. From the PHP request, store lookups for the ESB in a simple message queue (could just be a table in the database), which should be very quick to do. Then a separate long-lived “esb connector” process (eg ReactPHP or a simple loop) reads that queue and communicates to the ESB. The front-end can then poll for updates via AJAX or have the results pushed to it when available through a socket.

  • Variation on the previous item, you could also have your front-end requests connect to the “esb connector” process directly, through a socket or a standard http request. If the ESB itself is pretty quick except for the initial handshake, that would avoid having to setup a separate queue and from the front-end request, getting/processing the data would essentially be synchronous which may be easier depending on the use case.

While technically possible per your stack overflow link, serializing an object and storing it in the session (or elsewhere) seems like the wrong approach for something implemented in PHP.

Interesting discussion! :smile:

1 Like

Whoa, thanks a lot mark, you are always really helpful!, tons of new info to digest, got to say that I’m loving ReactPHP, never heard of it before. I Will dive into your suggestions and see how those works, but as you say, at the end I should be able to keep the “important” part of the connection, like tokens and so on stored, and manage the async operations between my crappy ESB and MODx using reactPHP, so I can guarantee a flawless UX no matter how much the esb missbehaves

Hi there, I got some time to play around with reactPhp and see how it works, and it’s totally the tool that I need, thanks for that pointer!, and sorry for the long replay but I’m trying to wrap my head around the whole thing.

What I have designed in general terms is as follows, one mainstream of events that helps me keep the UI updated, and for the actual async processes, long-running tasks, and other ‘features’ that the bus has, use promises to handle the async calls and delays from the bus, and when responses are received, notify the main stream so I can populate actions to the front end or PHP.

The thing that still confuses me, is that all the code I’ve played so far, either uses reactPhp owns server capability, or are just simple PHP programs that “keeps” on running on the internal react’s ‘loop’, so how do I plugin this concept, in the linear-execution that is natural to PHP and MODx?

And secondly, lol, I’m not sure if it’s my sturnbuorn java brain, but I feel like I got again to the issue of keeping state between request, for example, I have a “process” on a socket (yes, no soap, no rest, a tcp socket) that has a response time of 15~240mins, I know, its stupid, but its how the system works, so we need to either notify the user after 250mins to run another task to “unlock” the process, or if we actually got a response from the server stream, we must show this response to the user, so this should be cached independently of the user living requests.

What I’m finally getting is that I either need to have an instance of an object that is accessible for all requests for the user’s sesion lifetime, or I there need to be another PHP process running on apache that communicates with my MODx and helps me manage everything as related? lol is that even possible

Pdta: Totally agree that the approach suggested in the link is the worst possible way