natcap / invest

InVEST®: models that map and value the goods and services from nature that sustain and fulfill human life.
Apache License 2.0
157 stars 65 forks source link

Workbench cannot handle wind energy's debug logging from Taskgraph #1497

Open davemfish opened 8 months ago

davemfish commented 8 months ago

Rob gave us a datastack that includes a large wind_data_path CSV input. It's about 5MB, which is 2-3x larger than our sample data CSV. When Taskgraph logging level is set to DEBUG, a single line that is more than 18 million characters long is logged. This causes the Workbench renderer to consume an unreasonable amount of memory and ultimately crash.

The line begins,

2024-01-04 14:56:17,380 (taskgraph.Task) Task.is_precalculated(1166) DEBUG other_arguments: [[{0: {'LONG': -124.255, 'LATI': 46.9703, 'REF_LAM': 8.42, 'K': 1.92, 

That other_argument is the wind_data argument in,

compute_density_harvested_task = task_graph.add_task(
    func=_compute_density_harvested_fields,
    args=(wind_data, parameters_dict, number_of_turbines,
          wind_data_pickle_path),
    target_path_list=[wind_data_pickle_path],
    task_name='compute_density_harvested_fields')

For some reason, instead of passing the CSV as an argument to _compute_density_harvested_fields, we first read the CSV into a dict and pass that, so wind_data here is a dict. I don't see any reason why we need to do this, so passing the CSV into the function would avoid this logging problem.

Should the workbench more gracefully handle logging lines that are this long? Perhaps.

davemfish commented 8 months ago

Doug and I talked about possibly dis-allowing Taskgraph's DEBUG logging to reach the Workbench at all, only every allowing it to go the file handler. But that might involve some other tough decisions. Some options to accomplish this,

So far I'm inclined to leave the Workbench logging as-is, assuming we can make it perform adequately.

davemfish commented 8 months ago

Here's the ultimate crash from the Workbench. Out-of-memory.

[1] Error sending from webFrameMain:  Error: Render frame was disposed before WebFrameMain could be accessed
[1]     at s.send (node:electron/js2c/browser_init:2:93158)
[1]     at _.send (node:electron/js2c/browser_init:2:78814)
[1]     at C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\electronApi.js:205:23
[1]     at Array.forEach (<anonymous>)
[1]     at sendIpcToRenderer (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\electronApi.js:203:42)
[1]     at Object.sendIpc (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\electronApi.js:185:5)
[1]     at transport (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\transports\ipc.js:40:17)
[1]     at runTransport (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\log.js:44:5)
[1]     at runTransports (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\log.js:27:7)
[1]     at log (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\log.js:21:3)
[1] [10:27:51.012] [undefined] { reason: 'oom', exitCode: -536870904 }
[1] Error sending from webFrameMain:  Error: Render frame was disposed before WebFrameMain could be accessed
[1]     at s.send (node:electron/js2c/browser_init:2:93158)
[1]     at _.send (node:electron/js2c/browser_init:2:78814)
[1]     at C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\electronApi.js:205:23
[1]     at Array.forEach (<anonymous>)
[1]     at sendIpcToRenderer (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\electronApi.js:203:42)
[1]     at Object.sendIpc (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\electronApi.js:185:5)
[1]     at transport (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\transports\ipc.js:40:17)
[1]     at runTransport (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\log.js:44:5)
[1]     at runTransports (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\log.js:27:7)
[1]     at log (C:\Users\dmf\projects\invest\workbench\node_modules\electron-log\src\log.js:21:3)

I saw memory usage get up to 8 or 9 GB which seems strange when the entire logfile itself is only 159MB. So perhaps there is a memory leak here.

davemfish commented 7 months ago

The renderer's memory use is also very high when displaying a pre-existing logfile, such as from a recently completed invest run. For example, a logfile that is 25MB on disk causes the renderer to use ~1GB of memory when displaying the log. Closing the model tab does not immediately free the memory, though it does eventually. And then baseline memory use for the renderer is about 100 MB.