docs: function runCached (args, methodMeta) {
      // get cache data from method meta data
      var cache = methodMeta.cache
      // generate cache key
      var key = cache.keyMethod
          // call custom key generation method if defined
          ? (cache.keyMethod)(args, methodMeta)
          // use default key generation method
          : getCacheKey(args, methodMeta)
      // attempt to get value from cache
      return cache.cacheClient.get(key, args.session)
      // cache get success
      .then(res => {
          // cached value not found
          if (res === null) {
              // cached value not found, call method
              return runNotCached(args, methodMeta)
              // if method call resolves then cache results
              .then(res => {
                  // cache result if not null
                  if (res !== null) {
                      cache.expire
                          // cache response with expiration
                          ? cache.cacheClient.setex(key, res, cache.expire, args.session)
                          // cache response without expiration
                          : cache.cacheClient.set(key, res, args.session)
                  }
                  // resolve with response
                  return res
              })
          }
          // cached value found
          else {
              // if result is object then add cache key to it
              if (typeof res === 'object') {
                  res._cached = key
              }
              // resolve with response
              return res
          }
      })
      // cache get error
      .catch(err => {
          // if cache get had error then call method
          return runNotCached(args, methodMeta)
          // if method call resolves then cache results
          .then(res => {
              // cache result if not null
              if (res !== null) {
                  cache.expire
                      // cache response with expiration
                      ? cache.cacheClient.setex(key, res, cache.expire, args.session)
                      // cache response without expiration
                      : cache.cacheClient.set(key, res, args.session)
              }
              // resolve with response
              return res
          })
      })
  }