2016-06-21 2 views
-1

IWie zwei einen Durchlauf andere in Google Guave Cache als Schlüssel mehr Parameter übergeben

hier einen Cache mit Google Guave-Cache erstellen müssen, ist meine Implementierung davon

private final LoadingCache<Long, DistChannel> channelServiceCache = CacheBuilder.newBuilder().maximumSize(50) 
     .refreshAfterWrite(4, TimeUnit.HOURS).build(new CacheLoader<Long, DistChannel>() { 

      @Override 
      public DistChannel load(Long channelId) throws InvalidRequestException, TException { 
       long start = System.nanoTime(); 
       try { 
        return channelService.getDistributionChannelById(channelId, SOLR_API_KEY); 
       } catch (InvalidRequestException e) { 
        log.error("Cannot look up channel: {}", channelId, e); 
        String serviceName = StringUtils.isNotBlank(e.getServiceName()) ? e.getServiceName() : CHANNEL_SERVICE; 
        throw e.setServiceName(serviceName + "." + SERVICE_NAME + "." + hostName); 
       } finally { 
        log.info("Channel Service call, ChannelId: {} Time : {}", channelId, 
          TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)); 
       } 
      } 


      @Override 
      public ListenableFuture<DistChannel> reload(final Long channelId, final DistChannel oldValue) throws Exception { 
       ListenableFutureTask<DistChannel> task = ListenableFutureTask.create(new Callable<DistChannel>() { 
        public DistChannel call() { 
         long start = System.nanoTime(); 
         try { 
          return channelService.getDistributionChannelById(channelId, SOLR_API_KEY); 
         } catch (TException e) { 
          log.error("Cannot look up channel: {}", channelId, e); 
         }finally { 
          log.info("reload Channel Service call, ChannelId: {} Time : {}", channelId, 
            TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)); 
         } 
         return oldValue; 
        } 
       }); 
       executorServiceForCache.execute(task); 
       return task; 
      } 

     }); 

jetzt in channelService.getDistributionChannelById Verfahren Ich muss zwei Werte paaas nämlich ChannelId und apiKey.

Derzeit funktioniert es gut, da apiKey konstant ist. Aber jetzt ist apiKey zu diesem contant ~ timestamp modifiziert. zum Beispiel:

SOLR_API_KEY ~ 123456789

So Mein Problem ist:

Wie kann ich einen weiteren Parameter in channelServiceCache.get (Schlüssel, ExtraParam hier) passieren ohne Ändern des Schlüssels.

Sache, die ich versuchte: habe ich ein Key-Objekt, in dem mein eigentlichen Schlüssel sowie apikey anwesend sein und passiert, dass als Schlüssel in channelServiceCache Aber dies wird den Zweck der Cache als jeder töten töten wird als neuer Schlüssel angesehen, da er einen Zeitstempel in apikey enthält.

Gibt es eine Möglichkeit, das kann ich mit Google Guava tun?

EDIT: Eine weitere Sache, die ich verpasst haben:

Service geben gleiche Leistung für gleiche channelId, API-Schlüssel nur für die Authentifizierung und Protokollierung und Überwachung Abfragezahlen verwendet wird. Aber ich denke, es macht Sinn, wenn ich die nächste Anfrage mit der gleichen ChannelID aus dem Cache ausführen kann, dann wird apiKey niemals an den eigentlichen Service übergeben (wo die eigentliche Protokollierung und Überwachung stattfindet). Gibt es eine andere Möglichkeit, diese Funktionalität zu implementieren Tötungszweck von Google Guava.

+1

Ihre Problemdefinition scheint inkonsistent zu sein. Basierend auf Ihrer Beschreibung könnte man Ihre Anforderung erfüllen, indem Sie eine Schlüssel-Klasse implementieren, die sowohl die Kanal-ID als auch den API-Schlüssel enthält, aber Hash-Code implementiert und basierend auf der Kanal-ID gleich Soleloy ist. ** ABER ** warum in aller Welt sollte es nützlich sein: Es gibt einen Grund, warum Ihr ChannelService beide Argumente benötigt, um seinen Vertrag zu erfüllen. Wenn Sie die Kanal-ID unabhängig vom API-Schlüssel wiederverwenden können, warum sollten Sie sie dann überhaupt benötigen? – GPI

+0

Ich kann es aber seinen nicht konstanten Wert wiederverwenden. – Boola

Antwort

2

Wenn die Ausgabe des Service für jede Kanal-ID und jeden API-Schlüssel unterschiedlich ist, muss der API-Schlüssel Teil des Cache-Schlüssels sein.

Wenn die Ausgabe unabhängig vom API-Schlüssel identisch ist, können Sie einen beliebigen API-Schlüssel oder immer den gleichen API-Schlüssel verwenden.

Das Übergeben des API-Schlüssels vom Aufrufer, aber das Zwischenspeichern des Werts ist sinnlos oder im Wesentlichen identisch, um einen API-Schlüssel nach dem Zufallsprinzip auszuwählen. Sobald sich der Wert im Cache befindet, geben Sie ein Ergebnis zurück, das mit einem anderen API-Schlüssel vom vorherigen Aufrufer abgerufen wurde.

+0

Nein, der Dienst gibt dieselbe Ausgabe für die selbe Kanal-ID, der API-Schlüssel wird nur für die Authentifizierung und Protokollierung und Überwachung der Anforderungsanzahl verwendet. – Boola

+1

Vereinbarte mit @cruftex. Wenn 'service' den APIKey für * any * Zwecke verwendet, dann ist es Teil Ihres Cache-Schlüssels. Bsp .: Sie fragen einen neuen "Kanal" nach "id = 1, apiK = 1". 'channelService.getDistributionChannelById' wird aufgerufen, es wird" logging "für" apiKey = 1 "ausgeführt, Sie erhalten Ihr' DistChannel'-Objekt. Dann fordern Sie ein anderes für 'id = 1, apiKey = 2' an. Der Cache sollte Ihrer Meinung nach dieselbe "DistChannel" -Instanz enthalten. Daher sollte 'channelService.getDistributionChannelById' nicht aufgerufen werden und seine Protokollierung für apiKey = 2 sollte niemals stattfinden. Fazit: Sie brauchen es nicht/könnte auch einen beliebigen Wert verwenden. – GPI

+0

Es stellte sich heraus, dass meine Anforderungen genau das waren, was Sie sagten. Danke für das Aufzeigen dieses @GPI – Boola

Verwandte Themen