123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- import { ConnectionError, DataTypes, Model } from '@sequelize/core';
- import { Attribute, NotNull } from '@sequelize/core/decorators-legacy';
- import type { MsSqlConnection } from '@sequelize/mssql';
- import { AsyncQueueError } from '@sequelize/mssql';
- import { expect } from 'chai';
- import { beforeAll2, sequelize, setResetMode } from '../../support';
- describe('[MSSQL Specific] Async Queue', () => {
- if (!sequelize.dialect.name.startsWith('mssql')) {
- return;
- }
- setResetMode('none');
- const vars = beforeAll2(async () => {
- class User extends Model {
- @Attribute(DataTypes.STRING)
- @NotNull
- declare username: string;
- }
- sequelize.addModels([User]);
- await sequelize.sync({ force: true });
- await User.create({ username: 'John' });
- return { User };
- });
- it('should queue concurrent requests to a connection', async () => {
- await expect(
- sequelize.transaction(async transaction => {
- return Promise.all([
- vars.User.findOne({ transaction }),
- vars.User.findOne({ transaction }),
- ]);
- }),
- ).not.to.be.rejected;
- });
- it('requests that reject should not affect future requests', async () => {
- await expect(
- sequelize.transaction(async transaction => {
- await expect(vars.User.create({ username: new Date() })).to.be.rejected;
- await expect(vars.User.findOne({ transaction })).not.to.be.rejected;
- }),
- ).not.to.be.rejected;
- });
- it('closing the connection should reject pending requests', async () => {
- let promise;
- await expect(
- sequelize.transaction(async transaction => {
- promise = Promise.all([
- expect(sequelize.dialect.connectionManager.disconnect(transaction.getConnection())).to.be
- .fulfilled,
- expect(vars.User.findOne({ transaction }))
- .to.be.eventually.rejectedWith(
- ConnectionError,
- 'the connection was closed before this query could be executed',
- )
- .and.have.property('cause')
- .that.instanceOf(AsyncQueueError),
- expect(vars.User.findOne({ transaction }))
- .to.be.eventually.rejectedWith(
- ConnectionError,
- 'the connection was closed before this query could be executed',
- )
- .and.have.property('cause')
- .that.instanceOf(AsyncQueueError),
- ]);
- return promise;
- }),
- ).to.be.rejectedWith(
- ConnectionError,
- 'the connection was closed before this query could be executed',
- );
- await expect(promise).not.to.be.rejected;
- });
- it('closing the connection should reject in-progress requests', async () => {
- let promise;
- await expect(
- sequelize.transaction(async transaction => {
- const connection = transaction.getConnection() as MsSqlConnection;
- const wrappedExecSql = connection.execSql;
- connection.execSql = async function execSql(...args) {
- await sequelize.dialect.connectionManager.disconnect(connection);
- return wrappedExecSql.call(this, ...args);
- };
- promise = expect(vars.User.findOne({ transaction }))
- .to.be.eventually.rejectedWith(
- ConnectionError,
- 'the connection was closed before this query could finish executing',
- )
- .and.have.property('cause')
- .that.instanceOf(AsyncQueueError);
- return promise;
- }),
- )
- .to.be.eventually.rejectedWith(
- ConnectionError,
- 'the connection was closed before this query could be executed',
- )
- .and.have.property('cause')
- .that.instanceOf(AsyncQueueError);
- await expect(promise).not.to.be.rejected;
- });
- });
|