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

Allow passing a connection from publish to executeSql #200

Closed
wants to merge 1 commit into from

Conversation

ibash
Copy link

@ibash ibash commented Oct 17, 2020

Adds the option to pass a connection from publish to executeSql.
This allows creating transactions that encompass inserting jobs.

The test seems a bit messy, open to suggestions.

Fixes #199

Adds the option to pass a connection from publish to executeSql.
This allows creating transactions that encompass inserting jobs.
@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 4ffdcf1 on ibash:master into 6fcf398 on timgit:master.

@@ -1,6 +1,6 @@
declare namespace PgBoss {
interface Db {
executeSql(text: string, values: any[]): Promise<{ rows: any[]; rowCount: number }>;
executeSql(text: string, values: any[], options?: ExecutionOptions): Promise<{ rows: any[]; rowCount: number }>;
Copy link

Choose a reason for hiding this comment

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

Maybe this ? can be removed. It looks like options will always be defined based on how its called.

Copy link
Author

Choose a reason for hiding this comment

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

There's a few places where executeSql is called without any values too: https://github.com/timgit/pg-boss/blob/master/src/contractor.js#L26

I'm not super familiar with typescript, is that valid?

Copy link

Choose a reason for hiding this comment

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

My bad! I assumed executeSql was only called there

@gavacho
Copy link

gavacho commented Nov 5, 2020

@timgit What do you think about this patch?

@timgit
Copy link
Owner

timgit commented Nov 10, 2020

A couple things I'd like to see in this PR.

  1. Standardize on a db contract so it matches the interface used in the constructor. It's assumed that query() exists, but when we pass a custom db in the constructor, it's executeSql().
  2. The only way to use a custom db connection during publish() requires a custom db in the constructor. Some users may not know this and skip the constructor step. If this is how it should behave, this mismatch should throw an error. Another alternative would be to not require the custom db in the constructor and let the publish simply call that passed db object entirely.

@ibash
Copy link
Author

ibash commented Nov 15, 2020

Playing catchup on a few things and might not have time to get at this for a few days.

Looking at it with fresh eyes, 100% agree the interface is kind of weird.

Another alternative would be to not require the custom db in the constructor and let the publish simply call that passed db object entirely.

Are you saying instead of this:

await boss.publish({ name: 'passConnection', options: { connection } })

We instead pass in a db object? like this?

const wrapper = {
  async executeSql(text, values) {
    // up to user to do connection.query here ...
  }
}
await boss.publish({ name: 'passConnection', options: { db: wrapper } })

It's a bit more work, but would make it obvious that executeSql is the only thing that matters.

Or, could even do something like this:

const executeSql = async (text, values) => {
  // up to user to do connection.query here ...
}
await boss.publish({ name: 'passConnection', options: { executeSql } })

Personally I prefer the last form, as it gets straight to the point.

@timgit
Copy link
Owner

timgit commented Nov 18, 2020

Yes, this form aligns with the constructor option, which makes it a bit more clear of what the intention is.

await boss.publish({ name: 'passConnection', options: { db: wrapper } })

I agree it's a bit more setup for the caller, but this should make the internals a bit more ignorant of what's going on. The goal would be to simply swap out the normal db service with an override if it's passed in. This should make publish() ignorant of why a custom db is being passed in. I agree that using transactions would be the most common use case, but this doesn't have to be a "transaction" feature of pg-boss in order to pull it off.

@timgit timgit closed this Aug 10, 2021
@alexopenkowski-the-nu-company

Sad that this has never made it into some release. Inserting directly into the job table to use transactions feels a bit error-prone to me, especially when things change under the hood.

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

Successfully merging this pull request may close these issues.

publishing in a transaction
5 participants