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

transform in parallel does not work and messes with process #92

Closed
betafcc opened this issue Jan 9, 2020 · 3 comments · Fixed by #98
Closed

transform in parallel does not work and messes with process #92

betafcc opened this issue Jan 9, 2020 · 3 comments · Fixed by #98
Assignees
Labels

Comments

@betafcc
Copy link

betafcc commented Jan 9, 2020

Describe the bug

If you call transform before it's previous invocation has returned, it seems to drop the previous promise somehow

eg:

const { transform } = require('camaro')

const doit = () => transform('<foo>bar</foo>', { foo: 'foo' })

doit().then(_ => console.log('done 1'), console.error)
doit().then(_ => console.log('done 2'), console.error)

output

done 2

Even weirder, if you force Promise.all([doit(), doit()]) it seems to mess up with the whole process!

const { transform } = require('camaro')

const sleep = t => new Promise(resolve => setTimeout(resolve, t))

const doit = () => transform('<foo>bar</foo>', { foo: 'foo' })

const main = async () => {
  const sleeper = sleep(3000).then(_ => console.log('done sleeping')) // enqueu before, do run after 3 seconds

  try {
    const r = await Promise.all([doit(), doit()])
  } finally {
    console.log('finally block') // never runs
  }

  await sleeper
  console.log('after awaiting sleeper') // never runs
}

main()

This scripts waits 3 seconds to exit but only outputs 'done sleeping'

  • camaro version: 4.0.8, 4.1.2
  • Node version: v8.16.0, v10.16.0, v12.14.0, v13.5.0
  • Operating system: Linux Mint 19.1 Tessa

In camaro 3.0.19 it does work fine

@tuananh
Copy link
Owner

tuananh commented Jan 10, 2020

Thanks. Let me take a look at it.

@tuananh
Copy link
Owner

tuananh commented Jan 14, 2020

please expect this to take sometimes as i'm having a new newborn baby atm.

or you can try using v3 in the mean time.

i suspect that happens because the way i cache the instance but i'm not sure.

@tuananh tuananh self-assigned this Jan 16, 2020
@tuananh tuananh added the bug label Jan 16, 2020
@betafcc
Copy link
Author

betafcc commented Jan 27, 2020

Wow, congrats man :3

I've been using this workaround since then:

import { transform as unsafeTransform } from 'camaro'

export const locked = <A extends Array<unknown>, B>(
  f: (...a: A) => Promise<B>
): ((...a: A) => Promise<B>) => {
  let lock = Promise.resolve()

  return (...a) =>
    new Promise((resolve, reject) => {
      lock = lock.then(_ => f(...a).then(resolve, reject))
    })
}

export const transform = locked(unsafeTransform)

Just locking the function to only run after the previous invocation has resolved

tuananh added a commit that referenced this issue Apr 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants