0

When starting script below, I got an error that stuck on

Something bad heppened while waiting for index created
Index `createdAt` was not found on table `olive.todos`
r.table("todos").indexWait("createdAt")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

but starting script again, I have no problem.

Is this RethinkDB's problem or mine? And tell me the solution.

const createIndex = (conn, tableName, indexName) =>
  r.table(tableName).indexList().contains(indexName)
    .do(containsIndex =>
      r.branch(
        containsIndex,
        { created: 0 },
        r.table(tableName).indexCreate(indexName)
      )
    )
    ...

const waitForIndex = (conn, tableName, indexName) =>
  r.table(tableName).indexWait(indexName)
    ...

export const setup = startApp => {
  r.connect(config.rethinkdb)
    ...
    .then(conn => {
      Promise.all([
        createIndex(conn, 'todos', 'createdAt'),
        createIndex(conn, 'days', 'date'),
      ]);
      return conn;
    })
    .then(conn =>
      Promise.all([
        waitForIndex(conn, 'todos', 'createdAt'),
        waitForIndex(conn, 'days', 'date'),
      ])
    )
    ...
};
nishitani
  • 3
  • 1

2 Answers2

1

You seems mixed the API of different Promise API. I don't see you import Promise from anywhere. I supposed you are using built-in JavaScript Promise https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

When you use Promise.all, you have to chain it with then, instead of using return as next statement. Chain to then with resolver/reject.

Your code use return so right after Promise.all but you don't call then, so it returns instanly and the index hasn't ready to be created yet.

This code works:

import r from 'rethinkdb';
import config from '../config';

const createDatabase = (conn, name) =>
  r.dbList().contains(name)
    .do(containsDb =>
      r.branch(
        containsDb,
        { created: 0 },
        r.dbCreate(name)
      )
    )
    .run(conn)
    .error(err => {
      console.log(`Could not create ${name} DB`);
      console.log(err.message || 'Something bad happened');
      process.exit(1);
    });

const createTable = (conn, name) =>
  r.tableList().contains(name)
    .do(containsTable =>
      r.branch(
        containsTable,
        { created: 0 },
        r.tableCreate(name)
      )
    )
    .run(conn)
    .error(err => {
      console.log(`Could not create ${name} table`);
      console.log(err.message || 'Somthing bad happened');
      process.exit(1);
    });

const createIndex = (conn, tableName, indexName) =>
  r.table(tableName).indexList().contains(indexName)
    .do(containsIndex =>
      r.branch(
        containsIndex,
        { created: 0 },
        r.table(tableName).indexCreate(indexName)
      )
    )
    .run(conn)
    .error(err => {
      console.log(`Could not crate index ${indexName} in ${tableName}`);
      console.log(err.message || 'Something bad happened');
      process.exit(1);
    });

const waitForIndex = (conn, tableName, indexName) =>
  r.table(tableName).indexWait(indexName)
    .run(conn)
    .error(err => {
      console.log('Something bad happened while waiting for index created');
      console.log(err.message || 'Something bad happened');
      process.exit(1);
    });

export const setup = startApp => {
  r.connect(config.rethinkdb)
    .then(conn => {
      createDatabase(conn, 'test');
      return conn;
    })
    .then(conn => {
      return Promise.all([
        createTable(conn, 'todos'),
        createTable(conn, 'days'),
      ]).then((result) => conn, (reason) => conn)
    })
    .then(conn => {
      return Promise.all([
        createIndex(conn, 'todos', 'createdAt'),
        createIndex(conn, 'days', 'date'),
      ]).then(() =>  conn, () => conn)
    })
    .then(conn => {
        return Promise.all([
          waitForIndex(conn, 'todos', 'createdAt'),
          waitForIndex(conn, 'days', 'date'),
        ])
      }
    )
    .then(() => {
      console.log('DB and tables are available, starting Koa ...');
      startApp();
    })
    .error(err => {
      console.log('Could not open a connection to initiailize the database');
      console.log(err.message || 'Something bad happened');
      process.exit(1);
    });
};

setup()

Notice that we have to use then to pass down conn object, not by returning

kureikain
  • 2,304
  • 2
  • 14
  • 9
  • Thanks! Now, I understand what's the problem. To ensure that `return conn` is called after `Promise.all` called, it is needed to chain with `then`. – nishitani May 03 '16 at 11:40
0

I think everything looks good but you're missing the .run(conn) part of the queries. Changing it to this should do it:

const createIndex = (conn, tableName, indexName) =>
  r.table(tableName).indexList().contains(indexName)
    .do(containsIndex =>
      r.branch(
        containsIndex,
        { created: 0 },
        r.table(tableName).indexCreate(indexName)
      )
    ).run(conn);
    ...

const waitForIndex = (conn, tableName, indexName) =>
  r.table(tableName).indexWait(indexName).run(conn)
    ...

export const setup = startApp => {
  r.connect(config.rethinkdb)
    ...
    .then(conn => {
      Promise.all([
        createIndex(conn, 'todos', 'createdAt'),
        createIndex(conn, 'days', 'date'),
      ]);
      return conn;
    })
    .then(conn =>
      Promise.all([
        waitForIndex(conn, 'todos', 'createdAt'),
        waitForIndex(conn, 'days', 'date'),
      ])
    )
    ...
};
dalanmiller
  • 3,467
  • 5
  • 31
  • 38
  • Thank you for answering, but `...` already contains `.run(conn)`, and there should be another problem. ( Sorry, for my omission... I couldn't paste all code cos it was too long.) – nishitani May 03 '16 at 01:22
  • All code available here, [https://gist.github.com/nishitaniyuki/cb579a0aba7821028e49c0d483a377cf](https://gist.github.com/nishitaniyuki/cb579a0aba7821028e49c0d483a377cf) – nishitani May 03 '16 at 01:28