2
votes

Connecting to a locally running bigtable emulator from node.js, I need to be able to determine if a particular row exists. While this works as expected for rows that do exist, if seems that row.exits() hangs indefinitely for keys not contained in the table.

Here's a minimal sample:

const { Bigtable } = require('@google-cloud/bigtable');
const btInstance = Bigtable().instance('test');
const table = btInstance.table('testTable');
const [tableExists] = await table.exists();
if (!exists) {
  await table.create();
  await table.createFamily('testFamily');
}
const row = await table.row('testkey');

console.log('Table existence ensured. Checking if row exists...');

// fine till here...
const [rowExists] = await row.exists();
// may never get here, if connected to the emulator and row *doesn't* exist

if (!rowExists) {
  console.log('Row doesn\'t exist!');
} else {
  console.log('Row already exists.');
}

When connecting to a live Google Cloud instance of Bigtable, the code runs fine: a nonexistent row is reported. When connecting to the emulator, however, if a row doesn't exist the code never goes past the row.exists() call; no error is thrown either.

Is there anything wrong with what I'm trying to do, or is some workaround possible (perhaps a different way to check if a row exists for a given key)?

2
What version of the emulator are you using? Either Cloud SDK version or Git hash if you built it yourself? - Gary Elliott
gcloud --version shows Google Cloud SDK 252.0.0; beta 2019.05.17 - eotnhaioe

2 Answers

1
votes

There seems to be typo in tableExists variable. Using the following example, I was able to reproduce the issue. Please follow updates here: https://github.com/googleapis/nodejs-bigtable/issues/555

mkdir cbt-hang
cd cbt-hang
npm init --yes
npm install @google-cloud/bigtable

cat <<- EOF > index.js
const Bigtable = require('@google-cloud/bigtable');

async function main() {
    console.log("getting instance" )
    const btInstance = Bigtable().instance('test');

    console.log("getting table" )
    const table = btInstance.table('testTable');

    console.log("checking table existence" )
    const [tableExists] = await table.exists();
    if (!tableExists) {
        console.log("creating table" )
        await table.create();
        console.log("creating family" )
        await table.createFamily('testFamily');
    }

    console.log("getting row" )
    const row = await table.row('testkey');

    console.log("checking row exists")
    const [rowExists] = await row.exists();

    if (!rowExists) {
      console.log('Row doesn\'t exist!');
    } else {
      console.log('Row already exists.');
    }
}
main().catch(e => console.log(e));
EOF

gcloud beta emulators bigtable start --host-port=localhost:8086 &
BIGTABLE_EMULATOR_HOST=localhost:8086 node index.js

kill %1
1
votes

Try using the grpc library instead of grpc-js, there seems to be an issue with that at the moment.

Update your code to add the grpc library and then use that for your connection to the instance.

// Imports the Google Cloud client library
const Bigtable = require('@google-cloud/bigtable');
//Import the regular grpc library
const grpc = require('grpc');

const bigtable = Bigtable();

async function quickstart() {
  // connect to the instance using the grpc library
  const instance = Bigtable({grpc, sslCreds: grpc.credentials.createInsecure()}).instance('test');

  // the rest is the same

You'll need to install grpc with "npm install grpc" Let me know how this goes.