Управление переводом на Amazon с помощью Redis

Мне нужно управлять передачей json с помощью aws от Amazon и сохранять кеш в redis.

async function translateSomething(trans, p1, sourceLan, targetLan) {
  var paramsName = {
    Text: p1,
    SourceLanguageCode: sourceLan,
    TargetLanguageCode: targetLan,
  };

  let myPromise = () =>
    new Promise((resolve, reject) => {
      trans.translateText(paramsName, function (err, data) {
        if (err) throw err;
        if (data) {
          console.log("translated", data.TranslatedText);
          resolve(data.TranslatedText);
        }
      });
    });

  let res = await myPromise();
  return res;
}
// and this function to check if the value is in the menu or not

function storeOrFound(p1, value, sourceLan, targetLan) {
  return redisClient.get(p1, async (err, result) => {
    if (err) console.log("err", err);
    if (result) {
      console.log("element is already in cache", JSON.parse(result).val);

      let tmp = JSON.parse(result).val;

      return tmp;
    } else {
      var translate = new AWS.Translate({ region: AWS.config.region });

      let val = await translateSomething(
        translate,
        value,
        sourceLan,
        targetLan,
      );

      redisClient.setex(
        p1,
        3600,
        JSON.stringify({ source: "Redis Cache", val }),
      );

      return val;
    }
  });
}
// and after i execute the query of the db i use this function to check if is present or not on the db or not

something().then((doc) => {
  for (let i = 0; i < doc.items.length; i++) {
    const menuRedisKeyName = `name:${doc.items[i].name}21`;
    doc.items[i].name = storeOrFound(
      menuRedisKeyName,
      doc.items[i].name,
      menuLang,
      targetLan,
    );
  }
  console.log("JSON", JSON.stringify(doc));
  res.end(JSON.stringify(doc));
});

Проблема в том, что метод storeOrFound возвращает true или false (потому что return redisClient.get возвращает true или false независимо от того, присутствует объект или нет. Есть идеи по решению этой проблемы? Также на консоли я вижу, что элемент console.log(" уже в кеше "..) печатается в конце. Я что-то пропустил при синхронизации?

1 ответ

Решение

Вы можете захотеть что-то вроде этого.

  • translateSomething а также checkCache возвращать обещания, поэтому вы можете легко использовать их в async/await код.
  • getFromCacheOrTranslate оборачивает эти два в асинхронную функцию.

В коде есть и некоторые будущие TODO-комментарии.

function translateSomething(translate, text, sourceLan, targetLan) {
  return new Promise((resolve, reject) => {
    translate.translateText(
      {
        Text: text,
        SourceLanguageCode: sourceLan,
        TargetLanguageCode: targetLan,
      },
      function (err, data) {
        if (err && !data) {
          reject(err);
          return;
        }
        console.log("translated", data.TranslatedText);
        resolve(data.TranslatedText);
      },
    );
  });
}

/**
 * Promisified version of `redisClient.get()`.
 */
function checkCache(key) {
  return new Promise((resolve, reject) => {
    redisClient.get(key, (err, result) => {
      if (err) {
        reject(err);
      }
      resolve(result);
    });
  });
}

async function getFromCacheOrTranslate(text, sourceLan, targetLan) {
  const key = `translate:${sourceLan}:${targetLan}:${text}`; // TODO: hash the text here for a shorter cache key
  let result = await checkCache(key);
  if (result) {
    // result was in cache, return it
    return JSON.parse(result);
  }
  // Otherwise save it to the cache and return it
  const translate = new AWS.Translate({ region: AWS.config.region });
  result = await translateSomething(translate, text, sourceLan, targetLan);
  redisClient.setex(key, 3600, JSON.stringify(result)); // Async result ignored here
  return result;
}

something().then(async (doc) => {
  // TODO: this could use `Promise.all` to do this in parallel
  for (let i = 0; i < doc.items.length; i++) {
    doc.items[i].name = await getFromCacheOrTranslate(
      doc.items[i].name,
      menuLang,
      targetLan,
    );
  }
  console.log("JSON", JSON.stringify(doc));
  res.end(JSON.stringify(doc));
});
Другие вопросы по тегам