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

Is there a polyfill ? #17

Open
GrosSacASac opened this issue Sep 29, 2021 · 4 comments
Open

Is there a polyfill ? #17

GrosSacASac opened this issue Sep 29, 2021 · 4 comments

Comments

@GrosSacASac
Copy link

No description provided.

@ljharb
Copy link
Member

ljharb commented Sep 29, 2021

I hope not; polyfills shouldn’t really exist or be used until stage 3, except as explanatory tools for the proposal itself.

@cowboyd
Copy link

cowboyd commented Aug 3, 2022

@ljharb why not? How do you really know an API is good until you try it out?

Anyway, regardless of the API, would love to have a saveable/restorable random seed generator. If anybody knows of one out there....

@ljharb
Copy link
Member

ljharb commented Aug 3, 2022

@cowboyd you can write a function that provides the same API without needing to actually polyfill anything.

@cowboyd
Copy link

cowboyd commented Aug 4, 2022

@ljharb agreed. What I was looking for would perhaps be more accurately called a maybefill.

In any event, for those coming here, I was able to accomplish serializing and deserializing the random seed state using the alea npm package https://github.com/coverslide/node-alea

The seed function has an importState() and exportState() that lets you continue from anywhere in the sequence of pseudo random numbers.

cowboyd added a commit to thefrontside/graphgen that referenced this issue Aug 4, 2022
Graph generation for large graphs can be very slow. For example, on
some projects, the generation time can be up to thirty seconds. This
introduces a lot of latency in restarting any environment that
requires simulated data. However, most of the time this latency is
completely and totally unecessary because the graph generation is
pseudo-random and thus deterministic. In other words, we're spending
billions of intense CPU cycles, and hours of developer time
regenerating the _same thing over and over again_!!

This implements the possibility of caching a graphgen by passing it a
`storage` API that it can use to put values into and pull values out
of. For each call to `create()` Graphgen will store the resulting
graph using a key derived from
1. the arguments to `create()`
2. a hash of the schema source
3. all prior calls to `create()`

This allows us to have a single cache store multiple generations paths for
multiple different schema versions without conflicting.

For example, let's say you have a schema source

```graphql
type Person {
  name: String!
}
```
and that for arguments sake, its `sha-256` hash is `abc`. The
following generation sequence:

```ts
create("Person", { name: "Bob" });
create("Person", { name: "Alice" });
```

will cache two versions of the graph at the following keys:

```
1. create("Person", {"name": "Bob" })@abc
2. create("Person", {"name": "Bob" }) -> create("Person", { "name": "Alice" })@abc
```

This means that it will disambiguate it from the inverse generation
sequence:

```ts
create("Person, { name: "Alice" });
create("Person, { name: "Bob" });
```

By the same token, the hash of the schema is appended to each key so
that different schemas shared different spaces. That way, you can
change the schema, or switch branches that contain schema changes,
without having to blow away your cache.

PRNG (pseudo random number generator) state
==========

We need the cache to save off the entire state of graph generator
which includes the pseudo random number generator. In other words, no
matter where you save off the cache, you should be able to resume on
top of it and still get the same results. However, finding a PRNG that
had this property was
[difficult](tc39/proposal-seeded-random#17)
but I eventually stumbled on the
[`Alea`](https://github.com/coverslide/node-alea)  package which is a
PRNG that has explicit support for restoring serialized state.

A note on synchronicity
=======================

This storage API must be synchronous because graphgen itself is
synchronous. However, we should revisit making this api async if we
can settle on a way to make graphgen asynchronous and lazy in the
future.

A follow-on consequence of making this API synchronous is that we are
forced to use the deprecated `createHash()` function because it is
synchronous while the replacement API which, while compatible with the
Web Crypto standard, is asynchronous.

1. switch to Alea
2. createHash is deprecated, but new API is async.
cowboyd added a commit to thefrontside/graphgen that referenced this issue Aug 4, 2022
Graph generation for large graphs can be very slow. For example, on
some projects, the generation time can be up to thirty seconds. This
introduces a lot of latency in restarting any environment that
requires simulated data. However, most of the time this latency is
completely and totally unecessary because the graph generation is
pseudo-random and thus deterministic. In other words, we're spending
billions of intense CPU cycles, and hours of developer time
regenerating the _same thing over and over again_!!

This implements the possibility of caching a graphgen by passing it a
`storage` API that it can use to put values into and pull values out
of. For each call to `create()` Graphgen will store the resulting
graph using a key derived from
1. the arguments to `create()`
2. a hash of the schema source
3. all prior calls to `create()`

This allows us to have a single cache store multiple generations paths for
multiple different schema versions without conflicting.

For example, let's say you have a schema source

```graphql
type Person {
  name: String!
}
```
and that for arguments sake, its `sha-256` hash is `abc`. The
following generation sequence:

```ts
create("Person", { name: "Bob" });
create("Person", { name: "Alice" });
```

will cache two versions of the graph at the following keys:

```
1. create("Person", {"name": "Bob" })@abc
2. create("Person", {"name": "Bob" }) -> create("Person", { "name": "Alice" })@abc
```

This means that it will disambiguate it from the inverse generation
sequence:

```ts
create("Person, { name: "Alice" });
create("Person, { name: "Bob" });
```

By the same token, the hash of the schema is appended to each key so
that different schemas shared different spaces. That way, you can
change the schema, or switch branches that contain schema changes,
without having to blow away your cache.

PRNG (pseudo random number generator) state
==========

We need the cache to save off the entire state of graph generator
which includes the pseudo random number generator. In other words, no
matter where you save off the cache, you should be able to resume on
top of it and still get the same results. However, finding a PRNG that
had this property was
[difficult](tc39/proposal-seeded-random#17)
but I eventually stumbled on the
[`Alea`](https://github.com/coverslide/node-alea)  package which is a
PRNG that has explicit support for restoring serialized state.

A note on synchronicity
=======================

This storage API must be synchronous because graphgen itself is
synchronous. However, we should revisit making this api async if we
can settle on a way to make graphgen asynchronous and lazy in the
future.

A follow-on consequence of making this API synchronous is that we are
forced to use the deprecated `createHash()` function because it is
synchronous while the replacement API which, while compatible with the
Web Crypto standard, is asynchronous.

1. switch to Alea
2. createHash is deprecated, but new API is async.
cowboyd added a commit to thefrontside/graphgen that referenced this issue Aug 4, 2022
Graph generation for large graphs can be very slow. For example, on
some projects, the generation time can be up to thirty seconds. This
introduces a lot of latency in restarting any environment that
requires simulated data. However, most of the time this latency is
completely and totally unecessary because the graph generation is
pseudo-random and thus deterministic. In other words, we're spending
billions of intense CPU cycles, and hours of developer time
regenerating the _same thing over and over again_!!

This implements the possibility of caching a graphgen by passing it a
`storage` API that it can use to put values into and pull values out
of. For each call to `create()` Graphgen will store the resulting
graph using a key derived from
1. the arguments to `create()`
2. a hash of the schema source
3. all prior calls to `create()`

This allows us to have a single cache store multiple generations paths for
multiple different schema versions without conflicting.

For example, let's say you have a schema source

```graphql
type Person {
  name: String!
}
```
and that for arguments sake, its `sha-256` hash is `abc`. The
following generation sequence:

```ts
create("Person", { name: "Bob" });
create("Person", { name: "Alice" });
```

will cache two versions of the graph at the following keys:

```
1. create("Person", {"name": "Bob" })@abc
2. create("Person", {"name": "Bob" }) -> create("Person", { "name": "Alice" })@abc
```

This means that it will disambiguate it from the inverse generation
sequence:

```ts
create("Person, { name: "Alice" });
create("Person, { name: "Bob" });
```

By the same token, the hash of the schema is appended to each key so
that different schemas shared different spaces. That way, you can
change the schema, or switch branches that contain schema changes,
without having to blow away your cache.

PRNG (pseudo random number generator) state
==========

We need the cache to save off the entire state of graph generator
which includes the pseudo random number generator. In other words, no
matter where you save off the cache, you should be able to resume on
top of it and still get the same results. However, finding a PRNG that
had this property was
[difficult](tc39/proposal-seeded-random#17)
but I eventually stumbled on the
[`Alea`](https://github.com/coverslide/node-alea)  package which is a
PRNG that has explicit support for restoring serialized state.

A note on synchronicity
=======================

This storage API must be synchronous because graphgen itself is
synchronous. However, we should revisit making this api async if we
can settle on a way to make graphgen asynchronous and lazy in the
future.

A follow-on consequence of making this API synchronous is that we are
forced to use the deprecated `createHash()` function because it is
synchronous while the replacement API which, while compatible with the
Web Crypto standard, is asynchronous.

1. switch to Alea
2. createHash is deprecated, but new API is async.
cowboyd added a commit to thefrontside/graphgen that referenced this issue Aug 4, 2022
Graph generation for large graphs can be very slow. For example, on
some projects, the generation time can be up to thirty seconds. This
introduces a lot of latency in restarting any environment that
requires simulated data. However, most of the time this latency is
completely and totally unecessary because the graph generation is
pseudo-random and thus deterministic. In other words, we're spending
billions of intense CPU cycles, and hours of developer time
regenerating the _same thing over and over again_!!

This implements the possibility of caching a graphgen by passing it a
`storage` API that it can use to put values into and pull values out
of. For each call to `create()` Graphgen will store the resulting
graph using a key derived from
1. the arguments to `create()`
2. a hash of the schema source
3. all prior calls to `create()`

This allows us to have a single cache store multiple generations paths for
multiple different schema versions without conflicting.

For example, let's say you have a schema source

```graphql
type Person {
  name: String!
}
```
and that for arguments sake, its `sha-256` hash is `abc`. The
following generation sequence:

```ts
create("Person", { name: "Bob" });
create("Person", { name: "Alice" });
```

will cache two versions of the graph at the following keys:

```
1. create("Person", {"name": "Bob" })@abc
2. create("Person", {"name": "Bob" }) -> create("Person", { "name": "Alice" })@abc
```

This means that it will disambiguate it from the inverse generation
sequence:

```ts
create("Person, { name: "Alice" });
create("Person, { name: "Bob" });
```

By the same token, the hash of the schema is appended to each key so
that different schemas shared different spaces. That way, you can
change the schema, or switch branches that contain schema changes,
without having to blow away your cache.

PRNG (pseudo random number generator) state
==========

We need the cache to save off the entire state of graph generator
which includes the pseudo random number generator. In other words, no
matter where you save off the cache, you should be able to resume on
top of it and still get the same results. However, finding a PRNG that
had this property was
[difficult](tc39/proposal-seeded-random#17)
but I eventually stumbled on the
[`Alea`](https://github.com/coverslide/node-alea)  package which is a
PRNG that has explicit support for restoring serialized state.

A note on synchronicity
=======================

This storage API must be synchronous because graphgen itself is
synchronous. However, we should revisit making this api async if we
can settle on a way to make graphgen asynchronous and lazy in the
future.

A follow-on consequence of making this API synchronous is that we are
forced to use the deprecated `createHash()` function because it is
synchronous while the replacement API which, while compatible with the
Web Crypto standard, is asynchronous.

1. switch to Alea
2. createHash is deprecated, but new API is async.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants