anchor.diff:      token_revoked = false :: boolean(),
       cache_expiration :: timestamp()
   }).
  --type cache_item() :: #cache_item{}.
   
   -record(state, {
       cache_invalidation_timer = undefined :: undefined | reference()
  
positive.code: 
  
  %% @private
  -spec get_from_cache(token_auth(), Now :: timestamp()) ->
      {ok, cache_item()} | ?ERROR_NOT_FOUND.
  get_from_cache(TokenAuth, Now) ->
      try ets:lookup(?CACHE_NAME, TokenAuth) of
          [#cache_item{cache_expiration = Expiration} = Item] when Now < Expiration ->
              {ok, Item};
          _ ->
              ?ERROR_NOT_FOUND
      catch Type:Reason ->
          ?warning("Failed to lookup ~p cache (ets table) due to ~p:~p", [
              ?MODULE, Type, Reason
          ]),
          ?ERROR_NOT_FOUND
      end.
  
  
  %% @private
  -spec save_in_cache(cache_item()) -> ok.
  save_in_cache(Item) ->
      try
          ets:insert(?CACHE_NAME, Item),
          ok
      catch Type:Reason ->
          ?warning("Failed to save entry in ~p cache (ets table) due to ~p:~p", [
              ?MODULE, Type, Reason
          ]),
          ok
      end.
  
  
  %% @private
  -spec verify_token_auth(Now :: timestamp(), token_auth()) ->
      {verification_result(), VerificationResultExpiration :: timestamp()}.
  verify_token_auth(Now, #token_auth{
      access_token = SerializedAccessToken,
      peer_ip = PeerIp,
      interface = Interface,
      data_access_caveats_policy = DataAccessCaveatsPolicy
  }) ->
      CacheDefaultTTL = ?CACHE_ITEM_DEFAULT_TTL,
  
      case deserialize_token(SerializedAccessToken) of
          {ok, #token{subject = Subject} = Token} ->
              case token_logic:verify_access_token(
                  SerializedAccessToken, PeerIp, Interface,
                  DataAccessCaveatsPolicy
              ) of
                  {ok, Subject, undefined} ->
                      Auth = #auth{
                          subject = Subject,
                          caveats = tokens:get_caveats(Token)
                      },
                      {{ok, Auth, undefined}, Now + CacheDefaultTTL};
                  {ok, Subject, TokenTTL} ->
                      Auth = #auth{
                          subject = Subject,
                          caveats = tokens:get_caveats(Token)
                      },
                      Expiration = Now + min(TokenTTL, CacheDefaultTTL),
                      {{ok, Auth, Now + TokenTTL}, Expiration};
                  {error, _} = VerificationError ->
                      {VerificationError, Now + CacheDefaultTTL}
              end;
          {error, _} = DeserializationError ->
              {DeserializationError, Now + CacheDefaultTTL}
      end.
  
  
  
negative.code:     process_flag(trap_exit, true),
  
      ?CACHE_NAME = ets:new(?CACHE_NAME, [
          set, public, named_table, {keypos, #cache_entry.token_auth}
      ]),
      schedule_cache_size_checkup(),
  
  