[09:40:29] hm, lazy objects could potentially be useful in service wiring? [09:40:52] (re: tideways blog post) [09:41:13] I’m thinking of cases like hook handlers that are called often but will only need one of the injected services very rarely [09:42:15] (for the example of database connections in particular, we have some tests in Wikibase asserting that no service wiring directly opens a database connection, because Amir1 identified that as a performance issue years ago, but that’s specific to this one kind of “service”) [12:09:55] I'd say usually that's a sign that the extension might benefit from more granular hook handler classes [13:57:25] Lucas_WMDE: Depending on when that was, we have since made all Rdbms db objects lazily connecting so while it is imho still an anti-pattern to inject IDatabase at the service-level, one could in theory do that now without incurring a connection. [13:58:00] ref T255493, T312527, T236880 [13:58:01] T255493: Consider phasing out ILoadBalancer::getLazyConnectionRef in favour of ILoadBalancer::getConnectionRef - https://phabricator.wikimedia.org/T255493 [13:58:01] T312527: Flip deprecations of ConnectionManager::get*Connection(Ref) - https://phabricator.wikimedia.org/T312527 [13:58:01] T236880: Document when to use different ILoadBalancer::get*Connection* methods - https://phabricator.wikimedia.org/T236880 [13:58:32] TLDR: We made getConnection == getLazyConnectionRef, and deprecated/removed the other getConnection{Lazy,}{Ref,} variants [14:01:49] mszabo: something like passing a User object param that is lazily-created/casted from UserIdentity could be interesting perhaps, albeit a bit late. [14:02:28] This new php feature sounds a lot like the Stub feature MW used a lot years ago, e.g. UserStub and UserLanguageStub for $wgUser and $wgLang respectively. [14:02:40] I was about to say that Zend discovered https://github.com/wikimedia/mediawiki/blob/master/includes/StubObject/StubObject.php [14:02:53] StubUserLang StubGlobalUser * [14:02:56] yeah [14:05:12] hehe, true [14:05:35] but it sounds like it keeps the same object identity? (but I didn’t look at it in detail) [14:05:54] which would be more usable than StubObject which IIUC reassigns the relevant $wg global [14:08:06] seems to me that it might be a bit of a mess with the initialization code [14:08:35] we probably wouldn't want to have it inline in the wiring to allow it to be reused for normal init or tested [14:09:56] and at that point, might as well just refactor the problematic code to reduce the init cost [14:12:05] what could be interesting though is have the getX() in MediaWikiServices return a newLazyGhost( () => $services->getX()) [14:12:22] and effectively make the whole container fully lazy that way [14:13:20] could maybe do it in getService() too since that's overridden, but you lose type info there [14:13:39] (I’m not interested in discussing it based on 0 lines of actual code but I don’t think it makes sense to already conclude that the pattern I briefly described must be “problematic”, FWIW) [14:14:48] once we can actually use PHP 8.4 (so, in 2+ years? no idea) we can look more closely into where it might make sense / be useful, and also what its performance cost is :) [14:14:51] yeah it'd be entirely context dependent, I'm just finding it a bit hard to come up with a non-generic example [14:16:31] actually what I described with the container wouldn't work, because the callback taken by newLazyGhost() is supposed to lazy-initialize expensive properties instead of returning an object [14:17:18] so this is basically an automatism to avoid having to implement lazy getters by hand? [14:20:41] oh, there's newLazyProxy() which tideways didn't talk about: https://wiki.php.net/rfc/lazy-objects [14:20:55] > The initializer returns a new instance, and interactions with the proxy object are forwarded to this instance. [14:20:59] that seems much more useful :) [14:23:50] yeah, https://dailyrefactor.com/exploring-php-lazy-objects-practical-implementation talks a bit more about ghost objects vs. virtual proxies (I’ve only skimmed it so far) [14:24:45] yup, the proxy version seems more powerful since it doesn't require the initializer function to mutate the object's internal state [14:37:04] I imagine it also includes more overhead long-term, which is presumably the reason they implemented both instead of just the simpler proxy only. [14:37:27] I recall that RFC originally, I found it strange they choose to do both. Seems a bit much. [16:29:28] how is a lazy ghost different from classes like Title which have a load method called at the beginning of all their lazy getters? [16:30:06] (Other than the great name. "- Why is the site down? - Because of lazy ghosts.") [16:30:46] I guess it saves a method call per property access, but that seems like a trivial difference. [16:37:40] the RFC says "Unlike lazy initialization and value holders, proxies and ghost objects do not require a class to be written with the lazy-loading concept in mind. Instead, the lazy-loading behavior can be attached externally." [16:38:32] Any objection to changing namespace fields to smallint? More context in T383507 [16:38:33] T383507: Change data type of namespace fields from int to smallint or mediumint - https://phabricator.wikimedia.org/T383507