From 8d89b9acccabe3ced7023c56c458261bb6c25f77 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 12:41:10 +0530 Subject: [PATCH 1/6] chore(main): release 7.17.0 (#2185) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore(main): release 7.17.0 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: surbhigarg92 Co-authored-by: Owl Bot --- CHANGELOG.md | 13 +++++++++++++ package.json | 2 +- protos/protos.d.ts | 2 +- protos/protos.js | 2 +- samples/package.json | 2 +- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68af50868..721922886 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,19 @@ [1]: https://www.npmjs.com/package/nodejs-spanner?activeTab=versions +## [7.17.0](https://github.com/googleapis/nodejs-spanner/compare/v7.16.0...v7.17.0) (2024-12-27) + + +### Features + +* Add the last statement option to ExecuteSqlRequest and ExecuteBatchDmlRequest ([#2196](https://github.com/googleapis/nodejs-spanner/issues/2196)) ([223f167](https://github.com/googleapis/nodejs-spanner/commit/223f167c1c9bc4da26155637eabbcabce5487ede)) +* Enable e2e tracing ([#2202](https://github.com/googleapis/nodejs-spanner/issues/2202)) ([3cc257e](https://github.com/googleapis/nodejs-spanner/commit/3cc257e99925594776b9a1886f0173ce2dfe904f)) + + +### Bug Fixes + +* Span events Issue 2166 ([#2184](https://github.com/googleapis/nodejs-spanner/issues/2184)) ([97ed577](https://github.com/googleapis/nodejs-spanner/commit/97ed5776dbdf5e90f8398fffea08e2a968045f9b)) + ## [7.16.0](https://github.com/googleapis/nodejs-spanner/compare/v7.15.0...v7.16.0) (2024-11-09) diff --git a/package.json b/package.json index 15d9004b1..8ab398153 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@google-cloud/spanner", "description": "Cloud Spanner Client Library for Node.js", - "version": "7.16.0", + "version": "7.17.0", "license": "Apache-2.0", "author": "Google Inc.", "engines": { diff --git a/protos/protos.d.ts b/protos/protos.d.ts index 2ada44c72..cd998e336 100644 --- a/protos/protos.d.ts +++ b/protos/protos.d.ts @@ -1,4 +1,4 @@ -// Copyright 2024 Google LLC +// Copyright 2025 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/protos/protos.js b/protos/protos.js index 6a0b1f694..11a95c1c7 100644 --- a/protos/protos.js +++ b/protos/protos.js @@ -1,4 +1,4 @@ -// Copyright 2024 Google LLC +// Copyright 2025 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/package.json b/samples/package.json index 82383126f..141968d42 100644 --- a/samples/package.json +++ b/samples/package.json @@ -17,7 +17,7 @@ "dependencies": { "@google-cloud/kms": "^4.0.0", "@google-cloud/precise-date": "^4.0.0", - "@google-cloud/spanner": "^7.16.0", + "@google-cloud/spanner": "^7.17.0", "protobufjs": "^7.0.0", "yargs": "^17.0.0" }, From 7898e0ce0477e2d4327822ac26a2674203b47a64 Mon Sep 17 00:00:00 2001 From: surbhigarg92 Date: Fri, 3 Jan 2025 16:40:27 +0530 Subject: [PATCH 2/6] fix: remove default global trace context propagator (#2209) Fixes #2208 --- src/index.ts | 2 -- src/instrument.ts | 9 --------- 2 files changed, 11 deletions(-) diff --git a/src/index.ts b/src/index.ts index f0f88a801..9281484c9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -85,7 +85,6 @@ import * as v1 from './v1'; import { ObservabilityOptions, ensureInitialContextManagerSet, - ensureContextPropagation, } from './instrument'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -378,7 +377,6 @@ class Spanner extends GrpcService { this._observabilityOptions?.enableEndToEndTracing ); ensureInitialContextManagerSet(); - ensureContextPropagation(); } /** diff --git a/src/instrument.ts b/src/instrument.ts index 2c7998733..e4cb8d283 100644 --- a/src/instrument.ts +++ b/src/instrument.ts @@ -27,7 +27,6 @@ import { Span, SpanStatusCode, context, - propagation, trace, INVALID_SPAN_CONTEXT, ROOT_CONTEXT, @@ -100,8 +99,6 @@ const { AsyncHooksContextManager, } = require('@opentelemetry/context-async-hooks'); -const {W3CTraceContextPropagator} = require('@opentelemetry/core'); - /* * This function ensures that async/await works correctly by * checking if context.active() returns an invalid/unset context @@ -121,14 +118,8 @@ function ensureInitialContextManagerSet() { } } -function ensureContextPropagation() { - propagation.setGlobalPropagator(new W3CTraceContextPropagator()); -} - export {ensureInitialContextManagerSet}; -export {ensureContextPropagation}; - /** * startTrace begins an active span in the current active context * and passes it back to the set callback function. Each span will From 9f77f9f60ca6c636085baead4d401577b98df5a4 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 18:08:46 +0000 Subject: [PATCH 3/6] chore(main): release 7.17.1 (#2210) :robot: I have created a release *beep* *boop* --- ## [7.17.1](https://togithub.com/googleapis/nodejs-spanner/compare/v7.17.0...v7.17.1) (2025-01-03) ### Bug Fixes * Remove default global trace context propagator ([#2209](https://togithub.com/googleapis/nodejs-spanner/issues/2209)) ([7898e0c](https://togithub.com/googleapis/nodejs-spanner/commit/7898e0ce0477e2d4327822ac26a2674203b47a64)), closes [#2208](https://togithub.com/googleapis/nodejs-spanner/issues/2208) --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please). --- CHANGELOG.md | 7 +++++++ package.json | 2 +- samples/package.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 721922886..253b60c08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://www.npmjs.com/package/nodejs-spanner?activeTab=versions +## [7.17.1](https://github.com/googleapis/nodejs-spanner/compare/v7.17.0...v7.17.1) (2025-01-03) + + +### Bug Fixes + +* Remove default global trace context propagator ([#2209](https://github.com/googleapis/nodejs-spanner/issues/2209)) ([7898e0c](https://github.com/googleapis/nodejs-spanner/commit/7898e0ce0477e2d4327822ac26a2674203b47a64)), closes [#2208](https://github.com/googleapis/nodejs-spanner/issues/2208) + ## [7.17.0](https://github.com/googleapis/nodejs-spanner/compare/v7.16.0...v7.17.0) (2024-12-27) diff --git a/package.json b/package.json index 8ab398153..a633f96b1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@google-cloud/spanner", "description": "Cloud Spanner Client Library for Node.js", - "version": "7.17.0", + "version": "7.17.1", "license": "Apache-2.0", "author": "Google Inc.", "engines": { diff --git a/samples/package.json b/samples/package.json index 141968d42..4b31e02b7 100644 --- a/samples/package.json +++ b/samples/package.json @@ -17,7 +17,7 @@ "dependencies": { "@google-cloud/kms": "^4.0.0", "@google-cloud/precise-date": "^4.0.0", - "@google-cloud/spanner": "^7.17.0", + "@google-cloud/spanner": "^7.17.1", "protobufjs": "^7.0.0", "yargs": "^17.0.0" }, From 3a3d8c70c130b3ce8fdb6382f05040501fa9de0d Mon Sep 17 00:00:00 2001 From: Alka Trivedi Date: Thu, 9 Jan 2025 10:53:34 +0530 Subject: [PATCH 4/6] refactor: test --- observability-test/database.ts | 24 ++++++++++++++++++------ package.json | 2 +- samples/package.json | 2 +- src/index.ts | 2 ++ src/instrument.ts | 9 +++++++++ test/database.ts | 27 +++++++++++++++++++++------ 6 files changed, 52 insertions(+), 14 deletions(-) diff --git a/observability-test/database.ts b/observability-test/database.ts index 3e61b7bf4..c7d389857 100644 --- a/observability-test/database.ts +++ b/observability-test/database.ts @@ -503,7 +503,6 @@ describe('Database', () => { }); describe('getSnapshot', () => { - let fakePool: FakeSessionPool; let fakeSessionFactory: FakeSessionFactory; let fakeSession: FakeSession; let fakeMultiplexedSession: FakeMultiplexedSession; @@ -2117,12 +2116,11 @@ describe('Database', () => { a: 'b', c: 'd', }; - - let fakePool: FakeSessionPool; let fakeSessionFactory: FakeSessionFactory; let fakeSession: FakeSession; let fakeSession2: FakeSession; let fakeMultiplexedSession: FakeMultiplexedSession; + let fakeMultiplexedSession2: FakeMultiplexedSession; let fakeSnapshot: FakeTransaction; let fakeSnapshot2: FakeTransaction; let fakeStream: Transform; @@ -2142,16 +2140,23 @@ describe('Database', () => { beforeEach(() => { fakeSessionFactory = database.sessionFactory_; fakeMultiplexedSession = new FakeMultiplexedSession(); + fakeMultiplexedSession2 = new FakeMultiplexedSession(); fakeSnapshot = new FakeTransaction( {} as google.spanner.v1.TransactionOptions.ReadOnly ); + fakeSnapshot2 = new FakeTransaction( + {} as google.spanner.v1.TransactionOptions.ReadOnly + ); fakeStream = through.obj(); + fakeStream2 = through.obj(); getSessionStub = ( sandbox.stub(fakeSessionFactory, 'getSession') as sinon.SinonStub ) .onFirstCall() - .callsFake(callback => callback(null, fakeMultiplexedSession)); + .callsFake(callback => callback(null, fakeMultiplexedSession)) + .onSecondCall() + .callsFake(callback => callback(null, fakeMultiplexedSession2)); ( sandbox.stub(fakeMultiplexedSession, 'snapshot') as sinon.SinonStub @@ -2159,6 +2164,8 @@ describe('Database', () => { sandbox.stub(fakeSnapshot, 'runStream').returns(fakeStream); + sandbox.stub(fakeSnapshot2, 'runStream').returns(fakeStream2); + sandbox.stub(fakeSessionFactory, 'isMultiplexedEnabled').returns(true); }); @@ -2274,6 +2281,8 @@ describe('Database', () => { code: grpc.status.NOT_FOUND, message: 'Session not found', } as grpc.ServiceError; + const endStub = sandbox.stub(fakeSnapshot, 'end'); + const endStub2 = sandbox.stub(fakeSnapshot2, 'end'); let rows = 0; database @@ -2281,6 +2290,8 @@ describe('Database', () => { .on('data', () => rows++) .on('error', err => { assert.strictEqual(err, sessionNotFoundError); + assert.strictEqual(endStub.callCount, 1); + assert.strictEqual(endStub2.callCount, 0); assert.strictEqual(rows, 0); provider.forceFlush(); @@ -2330,12 +2341,13 @@ describe('Database', () => { }); fakeStream.emit('error', sessionNotFoundError); + fakeStream2.push('row1'); + fakeStream2.push(null); }); }); describe('when GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSION is disable', () => { beforeEach(() => { - fakePool = database.pool_; fakeSessionFactory = database.sessionFactory_; fakeSession = new FakeSession(); fakeSession2 = new FakeSession(); @@ -2498,7 +2510,7 @@ describe('Database', () => { await traceExporter.forceFlush(); const spans = traceExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 2, 'Exactly 1 span expected'); + assert.strictEqual(spans.length, 2, 'Exactly 2 spans expected'); withAllSpansHaveDBName(spans); const actualSpanNames: string[] = []; diff --git a/package.json b/package.json index a633f96b1..15d9004b1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@google-cloud/spanner", "description": "Cloud Spanner Client Library for Node.js", - "version": "7.17.1", + "version": "7.16.0", "license": "Apache-2.0", "author": "Google Inc.", "engines": { diff --git a/samples/package.json b/samples/package.json index 4b31e02b7..82383126f 100644 --- a/samples/package.json +++ b/samples/package.json @@ -17,7 +17,7 @@ "dependencies": { "@google-cloud/kms": "^4.0.0", "@google-cloud/precise-date": "^4.0.0", - "@google-cloud/spanner": "^7.17.1", + "@google-cloud/spanner": "^7.16.0", "protobufjs": "^7.0.0", "yargs": "^17.0.0" }, diff --git a/src/index.ts b/src/index.ts index 9281484c9..f0f88a801 100644 --- a/src/index.ts +++ b/src/index.ts @@ -85,6 +85,7 @@ import * as v1 from './v1'; import { ObservabilityOptions, ensureInitialContextManagerSet, + ensureContextPropagation, } from './instrument'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -377,6 +378,7 @@ class Spanner extends GrpcService { this._observabilityOptions?.enableEndToEndTracing ); ensureInitialContextManagerSet(); + ensureContextPropagation(); } /** diff --git a/src/instrument.ts b/src/instrument.ts index e4cb8d283..2c7998733 100644 --- a/src/instrument.ts +++ b/src/instrument.ts @@ -27,6 +27,7 @@ import { Span, SpanStatusCode, context, + propagation, trace, INVALID_SPAN_CONTEXT, ROOT_CONTEXT, @@ -99,6 +100,8 @@ const { AsyncHooksContextManager, } = require('@opentelemetry/context-async-hooks'); +const {W3CTraceContextPropagator} = require('@opentelemetry/core'); + /* * This function ensures that async/await works correctly by * checking if context.active() returns an invalid/unset context @@ -118,8 +121,14 @@ function ensureInitialContextManagerSet() { } } +function ensureContextPropagation() { + propagation.setGlobalPropagator(new W3CTraceContextPropagator()); +} + export {ensureInitialContextManagerSet}; +export {ensureContextPropagation}; + /** * startTrace begins an active span in the current active context * and passes it back to the set callback function. Each span will diff --git a/test/database.ts b/test/database.ts index 5040b0c84..cccc5d32d 100644 --- a/test/database.ts +++ b/test/database.ts @@ -1992,7 +1992,6 @@ describe('Database', () => { let fakeSessionFactory: FakeSessionFactory; let fakeSession: FakeSession; let fakeSession2: FakeSession; - let fakePool: FakeSessionPool; let fakeMultiplexedSession: FakeMultiplexedSession; let fakeMultiplexedSession2: FakeMultiplexedSession; let fakeSnapshot: FakeTransaction; @@ -2018,22 +2017,31 @@ describe('Database', () => { fakeSnapshot = new FakeTransaction( {} as google.spanner.v1.TransactionOptions.ReadOnly ); + fakeSnapshot2 = new FakeTransaction( + {} as google.spanner.v1.TransactionOptions.ReadOnly + ); fakeStream = through.obj(); + fakeStream2 = through.obj(); getSessionStub = ( sandbox.stub(fakeSessionFactory, 'getSession') as sinon.SinonStub - ) - .onFirstCall() - .callsFake(callback => callback(null, fakeMultiplexedSession)); + ).onFirstCall() + .callsFake(callback => callback(null, fakeMultiplexedSession)) + .onSecondCall() + .callsFake(callback => callback(null, fakeMultiplexedSession2)); snapshotStub = sandbox .stub(fakeMultiplexedSession, 'snapshot') .returns(fakeSnapshot); + + sandbox.stub(fakeMultiplexedSession2, 'snapshot').returns(fakeSnapshot2); runStreamStub = sandbox .stub(fakeSnapshot, 'runStream') .returns(fakeStream); + sandbox.stub(fakeSnapshot2, 'runStream').returns(fakeStream2); + sandbox.stub(fakeSessionFactory, 'isMultiplexedEnabled').returns(true); }); @@ -2101,25 +2109,32 @@ describe('Database', () => { fakeStream.destroy(fakeError); }); - it('should throw an error on "Session not found"', done => { + it('should not retry on "Session not found" error', done => { const sessionNotFoundError = { code: grpc.status.NOT_FOUND, message: 'Session not found', } as grpc.ServiceError; + const endStub = sandbox.stub(fakeSnapshot, 'end'); + const endStub2 = sandbox.stub(fakeSnapshot2, 'end'); + let rows = 0; database.runStream(QUERY).on('error', err => { assert.strictEqual(err, sessionNotFoundError); + assert.strictEqual(endStub.callCount, 1); + assert.strictEqual(endStub2.callCount, 0); + assert.strictEqual(rows, 0); done(); }); fakeStream.emit('error', sessionNotFoundError); + fakeStream2.push('row1'); + fakeStream2.push(null); }); }); describe('when GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSION is disable', () => { beforeEach(() => { fakeSessionFactory = database.sessionFactory_; - fakePool = database.pool_; fakeSession = new FakeSession(); fakeSession2 = new FakeSession(); fakeSnapshot = new FakeTransaction( From f4779407622409d5bccbe66a2510d1cced33f3e8 Mon Sep 17 00:00:00 2001 From: Alka Trivedi Date: Thu, 9 Jan 2025 10:53:34 +0530 Subject: [PATCH 5/6] refactor: test --- observability-test/database.ts | 24 ++++++++++++++++++------ package.json | 2 +- protos/protos.d.ts | 2 +- protos/protos.js | 2 +- samples/package.json | 2 +- src/index.ts | 2 ++ src/instrument.ts | 9 +++++++++ test/database.ts | 26 ++++++++++++++++++++++---- 8 files changed, 55 insertions(+), 14 deletions(-) diff --git a/observability-test/database.ts b/observability-test/database.ts index 3e61b7bf4..c7d389857 100644 --- a/observability-test/database.ts +++ b/observability-test/database.ts @@ -503,7 +503,6 @@ describe('Database', () => { }); describe('getSnapshot', () => { - let fakePool: FakeSessionPool; let fakeSessionFactory: FakeSessionFactory; let fakeSession: FakeSession; let fakeMultiplexedSession: FakeMultiplexedSession; @@ -2117,12 +2116,11 @@ describe('Database', () => { a: 'b', c: 'd', }; - - let fakePool: FakeSessionPool; let fakeSessionFactory: FakeSessionFactory; let fakeSession: FakeSession; let fakeSession2: FakeSession; let fakeMultiplexedSession: FakeMultiplexedSession; + let fakeMultiplexedSession2: FakeMultiplexedSession; let fakeSnapshot: FakeTransaction; let fakeSnapshot2: FakeTransaction; let fakeStream: Transform; @@ -2142,16 +2140,23 @@ describe('Database', () => { beforeEach(() => { fakeSessionFactory = database.sessionFactory_; fakeMultiplexedSession = new FakeMultiplexedSession(); + fakeMultiplexedSession2 = new FakeMultiplexedSession(); fakeSnapshot = new FakeTransaction( {} as google.spanner.v1.TransactionOptions.ReadOnly ); + fakeSnapshot2 = new FakeTransaction( + {} as google.spanner.v1.TransactionOptions.ReadOnly + ); fakeStream = through.obj(); + fakeStream2 = through.obj(); getSessionStub = ( sandbox.stub(fakeSessionFactory, 'getSession') as sinon.SinonStub ) .onFirstCall() - .callsFake(callback => callback(null, fakeMultiplexedSession)); + .callsFake(callback => callback(null, fakeMultiplexedSession)) + .onSecondCall() + .callsFake(callback => callback(null, fakeMultiplexedSession2)); ( sandbox.stub(fakeMultiplexedSession, 'snapshot') as sinon.SinonStub @@ -2159,6 +2164,8 @@ describe('Database', () => { sandbox.stub(fakeSnapshot, 'runStream').returns(fakeStream); + sandbox.stub(fakeSnapshot2, 'runStream').returns(fakeStream2); + sandbox.stub(fakeSessionFactory, 'isMultiplexedEnabled').returns(true); }); @@ -2274,6 +2281,8 @@ describe('Database', () => { code: grpc.status.NOT_FOUND, message: 'Session not found', } as grpc.ServiceError; + const endStub = sandbox.stub(fakeSnapshot, 'end'); + const endStub2 = sandbox.stub(fakeSnapshot2, 'end'); let rows = 0; database @@ -2281,6 +2290,8 @@ describe('Database', () => { .on('data', () => rows++) .on('error', err => { assert.strictEqual(err, sessionNotFoundError); + assert.strictEqual(endStub.callCount, 1); + assert.strictEqual(endStub2.callCount, 0); assert.strictEqual(rows, 0); provider.forceFlush(); @@ -2330,12 +2341,13 @@ describe('Database', () => { }); fakeStream.emit('error', sessionNotFoundError); + fakeStream2.push('row1'); + fakeStream2.push(null); }); }); describe('when GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSION is disable', () => { beforeEach(() => { - fakePool = database.pool_; fakeSessionFactory = database.sessionFactory_; fakeSession = new FakeSession(); fakeSession2 = new FakeSession(); @@ -2498,7 +2510,7 @@ describe('Database', () => { await traceExporter.forceFlush(); const spans = traceExporter.getFinishedSpans(); - assert.strictEqual(spans.length, 2, 'Exactly 1 span expected'); + assert.strictEqual(spans.length, 2, 'Exactly 2 spans expected'); withAllSpansHaveDBName(spans); const actualSpanNames: string[] = []; diff --git a/package.json b/package.json index a633f96b1..15d9004b1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@google-cloud/spanner", "description": "Cloud Spanner Client Library for Node.js", - "version": "7.17.1", + "version": "7.16.0", "license": "Apache-2.0", "author": "Google Inc.", "engines": { diff --git a/protos/protos.d.ts b/protos/protos.d.ts index cd998e336..2ada44c72 100644 --- a/protos/protos.d.ts +++ b/protos/protos.d.ts @@ -1,4 +1,4 @@ -// Copyright 2025 Google LLC +// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/protos/protos.js b/protos/protos.js index 11a95c1c7..6a0b1f694 100644 --- a/protos/protos.js +++ b/protos/protos.js @@ -1,4 +1,4 @@ -// Copyright 2025 Google LLC +// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/samples/package.json b/samples/package.json index 4b31e02b7..82383126f 100644 --- a/samples/package.json +++ b/samples/package.json @@ -17,7 +17,7 @@ "dependencies": { "@google-cloud/kms": "^4.0.0", "@google-cloud/precise-date": "^4.0.0", - "@google-cloud/spanner": "^7.17.1", + "@google-cloud/spanner": "^7.16.0", "protobufjs": "^7.0.0", "yargs": "^17.0.0" }, diff --git a/src/index.ts b/src/index.ts index 9281484c9..f0f88a801 100644 --- a/src/index.ts +++ b/src/index.ts @@ -85,6 +85,7 @@ import * as v1 from './v1'; import { ObservabilityOptions, ensureInitialContextManagerSet, + ensureContextPropagation, } from './instrument'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -377,6 +378,7 @@ class Spanner extends GrpcService { this._observabilityOptions?.enableEndToEndTracing ); ensureInitialContextManagerSet(); + ensureContextPropagation(); } /** diff --git a/src/instrument.ts b/src/instrument.ts index e4cb8d283..2c7998733 100644 --- a/src/instrument.ts +++ b/src/instrument.ts @@ -27,6 +27,7 @@ import { Span, SpanStatusCode, context, + propagation, trace, INVALID_SPAN_CONTEXT, ROOT_CONTEXT, @@ -99,6 +100,8 @@ const { AsyncHooksContextManager, } = require('@opentelemetry/context-async-hooks'); +const {W3CTraceContextPropagator} = require('@opentelemetry/core'); + /* * This function ensures that async/await works correctly by * checking if context.active() returns an invalid/unset context @@ -118,8 +121,14 @@ function ensureInitialContextManagerSet() { } } +function ensureContextPropagation() { + propagation.setGlobalPropagator(new W3CTraceContextPropagator()); +} + export {ensureInitialContextManagerSet}; +export {ensureContextPropagation}; + /** * startTrace begins an active span in the current active context * and passes it back to the set callback function. Each span will diff --git a/test/database.ts b/test/database.ts index 5040b0c84..10d8bba8c 100644 --- a/test/database.ts +++ b/test/database.ts @@ -1992,7 +1992,6 @@ describe('Database', () => { let fakeSessionFactory: FakeSessionFactory; let fakeSession: FakeSession; let fakeSession2: FakeSession; - let fakePool: FakeSessionPool; let fakeMultiplexedSession: FakeMultiplexedSession; let fakeMultiplexedSession2: FakeMultiplexedSession; let fakeSnapshot: FakeTransaction; @@ -2018,22 +2017,34 @@ describe('Database', () => { fakeSnapshot = new FakeTransaction( {} as google.spanner.v1.TransactionOptions.ReadOnly ); + fakeSnapshot2 = new FakeTransaction( + {} as google.spanner.v1.TransactionOptions.ReadOnly + ); fakeStream = through.obj(); + fakeStream2 = through.obj(); getSessionStub = ( sandbox.stub(fakeSessionFactory, 'getSession') as sinon.SinonStub ) .onFirstCall() - .callsFake(callback => callback(null, fakeMultiplexedSession)); + .callsFake(callback => callback(null, fakeMultiplexedSession)) + .onSecondCall() + .callsFake(callback => callback(null, fakeMultiplexedSession2)); snapshotStub = sandbox .stub(fakeMultiplexedSession, 'snapshot') .returns(fakeSnapshot); + sandbox + .stub(fakeMultiplexedSession2, 'snapshot') + .returns(fakeSnapshot2); + runStreamStub = sandbox .stub(fakeSnapshot, 'runStream') .returns(fakeStream); + sandbox.stub(fakeSnapshot2, 'runStream').returns(fakeStream2); + sandbox.stub(fakeSessionFactory, 'isMultiplexedEnabled').returns(true); }); @@ -2101,25 +2112,32 @@ describe('Database', () => { fakeStream.destroy(fakeError); }); - it('should throw an error on "Session not found"', done => { + it('should not retry on "Session not found" error', done => { const sessionNotFoundError = { code: grpc.status.NOT_FOUND, message: 'Session not found', } as grpc.ServiceError; + const endStub = sandbox.stub(fakeSnapshot, 'end'); + const endStub2 = sandbox.stub(fakeSnapshot2, 'end'); + const rows = 0; database.runStream(QUERY).on('error', err => { assert.strictEqual(err, sessionNotFoundError); + assert.strictEqual(endStub.callCount, 1); + assert.strictEqual(endStub2.callCount, 0); + assert.strictEqual(rows, 0); done(); }); fakeStream.emit('error', sessionNotFoundError); + fakeStream2.push('row1'); + fakeStream2.push(null); }); }); describe('when GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSION is disable', () => { beforeEach(() => { fakeSessionFactory = database.sessionFactory_; - fakePool = database.pool_; fakeSession = new FakeSession(); fakeSession2 = new FakeSession(); fakeSnapshot = new FakeTransaction( From b172004f8d52472d2fc19aed3c2b19615f18f2e6 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Thu, 9 Jan 2025 06:46:04 +0000 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- test/database.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/database.ts b/test/database.ts index cccc5d32d..10d8bba8c 100644 --- a/test/database.ts +++ b/test/database.ts @@ -2025,7 +2025,8 @@ describe('Database', () => { getSessionStub = ( sandbox.stub(fakeSessionFactory, 'getSession') as sinon.SinonStub - ).onFirstCall() + ) + .onFirstCall() .callsFake(callback => callback(null, fakeMultiplexedSession)) .onSecondCall() .callsFake(callback => callback(null, fakeMultiplexedSession2)); @@ -2033,8 +2034,10 @@ describe('Database', () => { snapshotStub = sandbox .stub(fakeMultiplexedSession, 'snapshot') .returns(fakeSnapshot); - - sandbox.stub(fakeMultiplexedSession2, 'snapshot').returns(fakeSnapshot2); + + sandbox + .stub(fakeMultiplexedSession2, 'snapshot') + .returns(fakeSnapshot2); runStreamStub = sandbox .stub(fakeSnapshot, 'runStream') @@ -2116,7 +2119,7 @@ describe('Database', () => { } as grpc.ServiceError; const endStub = sandbox.stub(fakeSnapshot, 'end'); const endStub2 = sandbox.stub(fakeSnapshot2, 'end'); - let rows = 0; + const rows = 0; database.runStream(QUERY).on('error', err => { assert.strictEqual(err, sessionNotFoundError);