Synchronize in-memory objects over multiple instances in IBM CLOUD Cloud Foundry Apps.
This is a short demo how can you synchronize in-memory objects over multiple instances in an IBM CLOUD Cloud Foundry App. When you use multiple instances in a IBM Cloud Foundry App (CF) and you use lists, arrays or objects to cache information in the memory you have to be careful with the refreshment of the cache. Because if you use an API Call to refresh the cache. Only the instances that the request hit will be updated. All others stay in the same condition as before. Because they don’t share the memory across the instances. That means each instance has an independent memory and they are not synchronized. Unfortunately there is no standard process designed in CF or IBM Cloud to fit this problem. Of course you can take a restart of your application. But if you have an application with a high availability this is not recommended.
The Problem
Initiated Cache after restart (synched)
API Call to one of the instances
Update the cache only on one Instance (out of synch)
The Solution
There is a simple way to refresh the cache from code side. You can access the following environment variables that contain the information you need. They are available for each CF Application.
- CF_INSTANCE_INDEX
- VCAP_APPLICATION
the VCAP_APPLICATION file contains the application_id that is needed to refresh the cache on all instances. Because with the following HTTP-Header you can call a specific instance:
-H “X-CF-APP-INSTANCE”:”APPLICATION_ID:YOUR-INSTANCE-INDEX”
Reference: https://docs.cloudfoundry.org/concepts/http-routing.html#app-instance-routing
The idea behind is to call iterative all instance to refresh the cache.
PSEUDO-CODE:
guid = os.gentenv(VCAP_APPLICATION)['application_id']
url = "https://" + os.gentenv(VCAP_APPLICATION)['application_uris'][0] + "/api/v1/refresh"instance = 0
another_instance = Truewhile instance:
try:
payload = ""
headers = {
'Content-Type': "application/json",
'X-CF-APP-INSTANCE': "guid :instance ",
'cache-control': "no-cache",
} response = requests.request("GET", url, data=payload, headers=headers)
instance += 1
except:
another_instance =False
Working Python Code:
https://github.com/cbernecker/refreshCacheonCloudFoundry
Working NodeJS Code:
https://github.com/pawanpinjarkar/refreshCacheOnCloudFoundry/tree/master/NodeJS
Working Bash Script:
https://github.com/pawanpinjarkar/refreshCacheOnCloudFoundry/tree/master/bash