Want to clear particular cache by using cache key in business rule

RajeshkumarV
Tera Contributor
Basically, I am trying to override function: getMySubscriptions from script include: ServiceSubscriptionUtilsSNC, because I want to add few more conditions on 
_addGroup function.
 
var SUBSCRIPTIONS_CACHE = 'SUBSCRIPTIONS_CACHE';


        // check the SUBSCRIPTIONS_CACHE if the there is an offering sys_ids array already associated to the user
        var userCachedSubscriptionsArr = sn_scoped_cache.ScopedCacheManager.get(SUBSCRIPTIONS_CACHE, userId);
  if (userCachedSubscriptionsArr)
            return JSON.parse(userCachedSubscriptionsArr);
 
I want to clear this SUBSCRIPTIONS_CACHE cache for particular user from business rule.
Tried the following, but didnt help.
 
Option_1:
var sm = GlideSecurityManager.get();

            sm.setUser(gs.getUser());

 

Option_2:

sn_scoped_cache.ScopedCacheManager.flushScopedCache("SUBSCRIPTIONS_CACHE");

 

Option_3:

var user = gs.getUserID();

sn_scoped_cache.ScopedCacheManager.flushScopedCache("SUBSCRIPTIONS_CACHE", user);

 

 

the only thing working as expected is, full flush: 

gs.cacheFlush();

 

But full flesh is not recommended. Please suggest any other approach. Thanks in advance.

3 REPLIES 3

RajeshkumarV
Tera Contributor

I am still stuck in this issue, could anyone please help here. Thank you.

Pavan Srivastav
ServiceNow Employee

Looking at your problem, the core issue is that sn_scoped_cache.ScopedCacheManager has scoped visibility — the cache written by the ServiceSubscriptionUtilsSNC script include (which runs in the sn_hr_service_portal or similar ServiceNow scope) can only be flushed from within that same scope.

Your Business Rule likely runs in a different scope (global or your custom scope), which is why flushScopedCache silently does nothing.


Root Cause

 
 
javascript
sn_scoped_cache.ScopedCacheManager.get(SUBSCRIPTIONS_CACHE, userId)
// ↑ This cache entry is namespaced to the scope that wrote it
// ↑ Only that same scope can flush it

Recommended Approaches

Option A — Script Include Bridge (Best Practice)

Create a Script Include in the same scope as ServiceSubscriptionUtilsSNC (e.g. sn_hr_service_portal) that exposes a flush method:

 
 
javascript
// Script Include: ServiceSubscriptionCacheUtils
// Scope: sn_hr_service_portal (same scope as ServiceSubscriptionUtilsSNC)
var ServiceSubscriptionCacheUtils = Class.create();
ServiceSubscriptionCacheUtils.prototype = {
    initialize: function() {},

    flushUserCache: function(userId) {
        sn_scoped_cache.ScopedCacheManager.flushScopedCache(
            'SUBSCRIPTIONS_CACHE', 
            userId
        );
    },

    type: 'ServiceSubscriptionCacheUtils'
};

Then call it from your Business Rule:

 
 
javascript
// Business Rule (any scope)
var cacheUtils = new sn_hr_service_portal.ServiceSubscriptionCacheUtils();
cacheUtils.flushUserCache(current.getValue('user')); // pass the user sys_id

This works because the flush executes within the owning scope.


Option B — Scripted REST / Background Script Workaround

If cross-scope Script Includes aren't available to you, trigger a Scripted REST API endpoint defined in the correct scope that performs the flush. Call it via RESTMessageV2 from your Business Rule.


Option C — Override getMySubscriptions to Skip Cache Conditionally

Since you're already overriding getMySubscriptions, you can add a bypass flag on the user session or a temp table, and check it before the cache read:

 
 
javascript
// In your overridden getMySubscriptions
var SUBSCRIPTIONS_CACHE = 'SUBSCRIPTIONS_CACHE';

// Check for bypass flag (e.g. set by your Business Rule via gs.getSession().putClientData)
var bypassCache = gs.getSession().getClientData('bypass_subscription_cache_' + userId);

if (!bypassCache) {
    var userCachedSubscriptionsArr = sn_scoped_cache.ScopedCacheManager.get(
        SUBSCRIPTIONS_CACHE, userId
    );
    if (userCachedSubscriptionsArr)
        return JSON.parse(userCachedSubscriptionsArr);
}

// clear the flag after use
gs.getSession().removeClientData('bypass_subscription_cache_' + userId);

Your Business Rule sets the flag:

 
 
javascript
// Business Rule
gs.getSession().putClientData(
    'bypass_subscription_cache_' + current.getValue('user'), 
    'true'
);

Summary

Option Works Cross-Scope Granular (per user) Recommended
flushScopedCache from BR
gs.cacheFlush() (too broad)
Script Include Bridge
Session bypass flag (if override available)

Option A (Script Include Bridge) is the cleanest and most maintainable — it respects scope boundaries without any workarounds.

RajeshkumarV
Tera Contributor

Option A — Script Include Bridge (Best Practice) - this worked.

But still the catalog items in service portal is not getting refreshed even after nullifying the cache. Still it is showing previous list only.