Skip to content

Conversation

alerque
Copy link
Collaborator

@alerque alerque commented Oct 3, 2025

Fixes #1825

... at least the increasing memory usage on each press of g is fixed by making new data structures and allowing the old data to be garbage collected. I'm not sure about CPU usage as that did not go up appreciably in my repro for this issue, and I haven't tested this long enough to know if it also solves the ‘leave running for days’ variant of the problem rather than the repeated manual refresh variant, but it seems likely it will.

@alerque alerque added the A-BUG Something wrong, confusing or sub-standard in the software, docs, or user experience. label Oct 3, 2025
@alerque alerque requested a review from simonmichael October 3, 2025 22:44
@alerque
Copy link
Collaborator Author

alerque commented Oct 4, 2025

See issue comments for updates on testing, I did do a longer term run test and got more conclusive results than the initial speculation here.

@simonmichael
Copy link
Owner

I haven't had much quality hacking time just lately - but I am loving this burst of activity, will follow up asap!

@alerque
Copy link
Collaborator Author

alerque commented Oct 6, 2025

I just converted this to a draft again because the latest commits here have not been properly vetted. I'm hacking wildly trying to make out where the leak(s) are. The current iteration runs much better for me including not leaking memory from the registry screen, but I haven't reasoned through everything enough to verify functionality won't have been lost.

Copy link
Owner

@simonmichael simonmichael left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice strictness investigations. I have noted some questions.

e | e `elem` [AppEvent FileChange, VtyEvent (EvKey (KChar 'g') [])] -> uiReload copts d ui >>= put'
e | e `elem` [AppEvent FileChange, VtyEvent (EvKey (KChar 'g') [])] -> do
ui' <- uiReload copts d ui
put' $ regenerateScreens (ajournal ui') d ui'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reloading in the register screen now has an extra call to regenerateScreens. Does this help ? I think it's also being called by uiReload. Needs an explanatory comment at least.

-- sendVtyEvents [EvKey KEnter [], EvKey (KChar 'g') []] -- XXX Might be disrupted if other events are queued
tsReload copts d ui = uiReload copts d ui >>= put'

tsReloadIfFileChanged copts d j ui = liftIO (uiReloadIfFileChanged copts d j ui) >>= put'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This special handling for regenerating transaction screen was added in 1.50.1 to fix #2288. It has been removed and I think not fully replaced by later commits ? Also is the comment above still accurate ?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PS a little more context, my understanding was that the right fix for #2288 would be to make regenerateScreens take parent screens' state into account (fold rather than map).

updatedTxn = case find (\t -> tindex t == tindex currentTxn) (jtxns j) of
Just t -> t
Nothing -> currentTxn -- fallback to current if not found
in tss { _tssTransaction = (currentIdx, updatedTxn) }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this replace the special regeneration previously in TransactionScreen.hs ?
Jumping to a different transaction after reload or file change is not ideal.
I think the old code exited to the register screen in that situation.

RS rss -> RS $! rsUpdate (aopts ui') d j rss
TS tss -> TS $! tsUpdate (aopts ui') d j tss
ES _ -> s
in ui'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen types and functions are listed explicitly in a bunch of places, so maybe it's no great loss to do that here also - but is it possible to achieve the same strictness without listing them all ?

More seriously, doesn't it now only regenerate the current screen ?

Copy link
Owner

@simonmichael simonmichael Oct 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Comments so far are based on code review, I haven't tested yet. Unfortunately it's easy to break behaviours in hledger-ui in ways that currently are hard to test, except manually.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-BUG Something wrong, confusing or sub-standard in the software, docs, or user experience.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

hledger-ui --watch consumes more CPU and RAM over time [$150 x 3]

2 participants