question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Services inheriting from common base need different caches.

See original GitHub issue

I really like Cacheable. And I really want it to work for my needs! However, it’s currently not working. Here’s my scenario:

I have a base service called Repository. All services inherit from it. When I fetch data from each child service, they share the same cache & the service that calls 2nd, gets the first service’s data.

The calls in the follow code block are nested for force an order for this example. Typically, there’s a race condition and whoever resolves first wins. The response in the 2nd call should be Widget[], however, it comes back as Part[] because of the cache.

this.partsService.find().subscribe((parts) => {
  this.parts = parts;

  this.widgetsService.find().subscribe((widgets) => {
    this.widgets = widgets;
  });
});

widgets.service.ts

import { RepositoryService } from './repository.service';
import { Widget } from '../models';

export class WidgetService extends RepositoryService<Widget> {}

parts.service.ts

import { RepositoryService } from './repository.service';
import { Part } from '../models';

export class PartService extends RepositoryService<Part> {}

repository.service.ts

import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable, Subject } from 'rxjs';
import { Cacheable, CacheBuster } from 'ngx-cacheable';
import { Resource } from '../models/resource.model';
import * as i from 'inflection';

const cacheBuster$ = new Subject<void>();

export class RepositoryService<T extends Resource> {
  private base:string = '/api';
  private collection:string;

  constructor(private http: HttpClient) {
    this.collection = i.underscore(i.pluralize(
      this.constructor.name.replace('Service', '')
    ));
  }

  @Cacheable({
    cacheBusterObserver: cacheBuster$
  })
  public find(query: object = {}): Observable<T[]> {
    const options = { params: new HttpParams() };

    for (const [key, value] of Object.entries(query)) {
      options.params.set(key, value);
    }

    return this.http.get<T[]>(this.url(), options);
  }

  @Cacheable({
    cacheBusterObserver: cacheBuster$
  })
  public findById(id: string): Observable<T> {
    return this.http.get<T>(this.url(id));
  }

  @CacheBuster({
    cacheBusterNotifier: cacheBuster$
  })
  public save(item: T): Observable<T> {
    return item.id ? this.update(item) : this.create(item);
  }

  private create(item: T): Observable<T> {
    return this.http.post<T>(this.url(), item);
  }

  private update(item: T): Observable<T> {
    const { id, ...payload } = <T>item;
    return this.http.patch<T>(this.url(id), payload);
  }

  private url(id?: string) {
    return [this.base, this.collection, id].filter(x => !!x).join('/');
  }
}

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
angelnikolovcommented, Jan 7, 2020

Hey, thanks for your question. Will take a look after work 😃

1reaction
jonstorercommented, Jan 7, 2020

is there a way to make const cacheBuster$ = new Subject<void>(); specific to each instance of each child service?

Read more comments on GitHub >

github_iconTop Results From Across the Web

DACs Inheritance and Caches - Acumatica Developers Blog
The main reason is polymorphism – Vendor DAC might customize some properties of BAccount DAC, so when you have same cache, you ensure...
Read more >
Server-side caching - Apollo GraphQL Docs
Most other fields can then inherit their cache hint from their parent (fields with resolvers that don't fetch data less commonly have specific...
Read more >
Caching guidance - Azure Architecture Center | Microsoft Learn
Caching is a common technique that aims to improve the performance and scalability of a system. It caches data by temporarily copying frequently...
Read more >
Caching in GitLab CI/CD
A cache is one or more files a job downloads and saves. Subsequent jobs that use the same cache don't have to download...
Read more >
ASP.NET Core 2 - Multiple Azure Redis Cache services DI
My questions how can I add another service that points to a different Azure Redis Cache Connection and instance and make separation of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found