feross / hostile

Simple, programmatic `/etc/hosts` manipulation (in node.js)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug: batch set

willin opened this issue · comments

import hostile from 'hostile';
import { promisify } from 'util';

const hostileSet = promisify(hostile.set);

Promise.all([
  hostileSet('1.2.3.4', 'test1'),
  hostileSet('1.2.3.5', 'test2'),
  hostileSet('1.2.3.4', 'test1'),
  hostileSet('1.2.3.4', 'test3')
]).then(console.log);
// [ undefined, undefined, undefined, undefined ]

in host file:

1.2.3.4 test1

only add one line


import hostile from 'hostile';
import sleep from 'sleep-promise';
import { promisify } from 'util';

const hostileSet = promisify(hostile.set);

Promise.all([
  (async () => {
    await sleep(200);
    await hostileSet('1.2.3.4', 'test1');
  })(),
  (async () => {
    await sleep(200);
    await hostileSet('1.2.3.5', 'test2');
  })(),
  (async () => {
    await sleep(200);
    await hostileSet('1.2.3.4', 'test1');
  })(),
  (async () => {
    await sleep(200);
    await hostileSet('1.2.3.4', 'test3');
  })()
]).then(console.log);
// [ undefined, undefined, undefined, undefined ]

in host file:

1.2.3.4 test1

only add one line

Since they're all modifying the file, I suggest not running them concurrently with Promise.all, but sequentially using https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/for-await...of

I just tried two paths and no luck with batching things up, cmd line stuff works fine

# 1

const hostile = require('hostile')

const HOSTS_TO_ADD = [
  ['127.0.0.1',	'api.domain.devwork'],
  ['127.0.0.1',	'app.domain.devwork'],
]

HOSTS_TO_ADD.forEach(async ([ip, host] = hostDefinition) => {
  await hostile.set(ip, host, function (err) {
    if (err) {
      console.error(err)
    } else {
      console.log(`set '${ip} ${host}' in '/etc/hosts' successfully!`)
    }
  })
})

# 2

const hostile = require('hostile')

function* hosts() {
  yield ['127.0.0.1',	'api.domain.devwork'];
  yield ['127.0.0.1',	'app.domain.devwork'];
}

(async function() {
  try {
    for await (const hostDefinition of hosts()) {
      const [ip, host] = hostDefinition
      hostile.set(ip, host, function (err) {
        if (err) {
          console.error(err)
        } else {
          console.log(`set '${ip} ${host}' in '/etc/hosts' successfully!`)
        }
      })
    }
  } catch (e) {
    console.log('caught', e)
  }
})();

hostile.set is not an async function and does not return a promise, so 'await hostile.set' will not actually wait until the get/set cycle is complete. (it would probably be a nice addition to the API though)

you will need to explicitly wait for the callback to execute if you want to forEach around it. something like

await new Promise( (resolve,reject) => hostile.set(ip, host, err => err ? reject(err) : resolve()))

hostile.set is not an async function and does not return a promise, so 'await hostile.set' will not actually wait until the get/set cycle is complete. (it would probably be a nice addition to the API though)

you will need to explicitly wait for the callback to execute if you want to forEach around it. something like

await new Promise( (resolve,reject) => hostile.set(ip, host, err => err ? reject(err) : resolve()))

thank you for point out things, thank you for code snippet but this also did not do the trick. just writes one line at time.