Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: emit files on demand and cache emit in sqlite db #15198

Closed
wants to merge 20 commits into from

Conversation

dsherret
Copy link
Member

@dsherret dsherret commented Jul 13, 2022

This change causes source files to be emitted on demand (emits should no longer get out of sync with sources except potentially with deno coverage), stores the emit cache in an sqlite database, and no longer stores the source maps inline in the emitted file (it only embeds source maps on the fly in a file if someone uses --inspect or --inspect-brk).

  • Test for TS file changing between running workers (should now work) Edit: nope it doesn't because it gets the source from the cached module graph, which seems reasonable. Will have to look into this later.
  • Unit tests for emit sqlite cache
  • Update https://deno.land/x/deno_cache -- Will do this after getting the thumbs up on this.
  • Test for emit cache not being able to be created.

Closes #13302
Closes #15124

Breaking Change

The emit file is no longer included with deno info --json.

@nayeemrmn
Copy link
Collaborator

We should have an alternative way of inspecting emit

@dsherret
Copy link
Member Author

dsherret commented Jul 13, 2022

@nayeemrmn we're going to add it to here: https://deno.land/x/deno_cache

Also, I'm thinking to develop a web server that can be run locally to look at the cache contents (maybe something in the deno_cache repo that can be run from the command line), but even just using something like DB Browser for SQLite is not too bad.

@nayeemrmn
Copy link
Collaborator

nayeemrmn commented Jul 13, 2022

I inspect emit often, though usually for checking transpilation/cache bugs. My workflow of deno info temp.ts -> ctrl+click emit path can be replaced by dcache show-emit temp.ts, so I hope https://deno.land/x/deno_cache will at least have an installable CLI which can do that.

@dsherret
Copy link
Member Author

@nayeemrmn yeah for sure. That would be really easy to do

pub struct CliModuleLoader {
pub lib: TsTypeLib,
/// The initial set of permissions used to resolve the static imports in the
/// worker. They are decoupled from the worker (dynamic) permissions since
/// read access errors must be raised based on the parent thread permissions.
pub root_permissions: Permissions,
pub ps: ProcState,
// the emit cache can only be used on one thread due to sqlite constraints
emit_cache: EmitCache,
Copy link
Member Author

Choose a reason for hiding this comment

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

I had to move a lot out of proc_state and into this file because EmitCache can only be used on a single thread whereas ProcState gets sent around all over the place.

),
err
);
Self(None)
Copy link
Member Author

Choose a reason for hiding this comment

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

A nice thing is the code can work fine without an emit cache now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any tests that demonstrate this? Like a read only cache dir? Feels like creating a tmp dir without read permissions would be a good test to ensure that code can still be emitted, just not cached.

Copy link
Member Author

Choose a reason for hiding this comment

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

No, but that would be good. I will add one.

@dsherret dsherret requested review from kitsonk and bartlomieju July 14, 2022 20:35
@dsherret dsherret marked this pull request as ready for review July 14, 2022 20:35
Copy link
Contributor

@kitsonk kitsonk left a comment

Choose a reason for hiding this comment

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

some thoughts and questions

cli/cache/disk_cache.rs Show resolved Hide resolved
),
err
);
Self(None)
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there any tests that demonstrate this? Like a read only cache dir? Feels like creating a tmp dir without read permissions would be a good test to ensure that code can still be emitted, just not cached.

cli/cache/incremental.rs Outdated Show resolved Hide resolved
Some(CacheInfo {
local: Some(local),
emit,
map,
// we no longer store the emit and map in their own files
Copy link
Contributor

Choose a reason for hiding this comment

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

this impacts the output of deno info mod.ts --json, which is a breaking change. It feels like this is something we should address in deno_graph or at least make a wider note of instead of sort of just stubbing it off.

Copy link
Member Author

@dsherret dsherret Jul 16, 2022

Choose a reason for hiding this comment

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

Yes, see the bottom of the PR description. It was agreed upon that breaking this was worth it in order to fix the issues.

That said, an alternative to not be breaking is to store a hash of the emit in addition to the source in the current version file. Then we would load the source, versions (two hashes), and emit then check that the emit hash matches the one in versions and the source hash matches the one in versions. If they do, then we can use the emit. By breaking here the main gain we get is that we don't need to bother hashing the emit... the more I think about it the more I would prefer this instead actually and it would be less work, though still breaking for deno_cache (because of change to versions file). Thoughts?

Edit: Oh, there is also the source map hash. That could just be moved back into the file.

Copy link
Member Author

Choose a reason for hiding this comment

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

It would be really easy to pivot this PR to that actually. I think I will try it out on Monday and see how it performs. I'm getting a little concerned depending on sqlite so much.

Copy link
Member Author

Choose a reason for hiding this comment

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

I got a bit carried away and opened this PR that does this: #15220 -- I think it's better

cli/emit.rs Show resolved Hide resolved
use test_util::TempDir;

#[test]
fn info_with_compiled_source() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why just remove the test... This is an strong indication that we are introducing a breaking change with deno info, something we should address.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it was removed because of the breaking change (address in PR description). This is testing if "emit: " is in the output on line 35 and that's no longer the case.

cli/text_encoding.rs Show resolved Hide resolved
@dsherret
Copy link
Member Author

dsherret commented Jul 18, 2022

Closing this in favour of #15220 as it's less breaking. Measured the performance of everything and both this and that PR have the same performance (about 15% faster than main on the test I was doing)

@dsherret dsherret closed this Jul 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants