Assigning value to Site variable from Server action

Assigning value to Site variable from Server action

  

I have a server action which is triggered by a timer. The server action waits for response from a REST API and if it gets any, I am assigning the response to a Site Variable and the cycle repeats itself.


I have a screen which has to wait for the Site Variable value change. If Site Variable value changes,  then the screen should be refreshed and accordingly values should be displayed in the screen and the process continues.

Now the problem is Site Variable value is not getting changed after assigning the response in Server action. When I debugged the Server Action, I could see value is getting assigned to the site variable. But When I debugged the screen, I could see only the default value of Site Variable not the changed the value. What is the solution for this? Is there any other way to achieve this instead of using Site Variable?

Please Help!

Hi Ananth.

The issue you're facing must be related to cache propagation between the servers in your Farm. Site Properties use a distribuited cache mechanism in order to gain in performance. So each Site Property has a version of its value on each Application Server. And when you change it, it takes a while to be propagate to all the servers in the Farm.

If you want to force the propagation, you need to use the System Action EspaceInvalidateCache. This way, whenever you change an SP value, it's gonna be propagated to all servers.


BUT!!! It's NOT recommended to keep changing Site Properties. Take a good look at this, this, and this. To briefly summarise, if you change a Site Property value, you're losing its main purpose, which is cache, that leads to performance. Try to use Site Properties with what it's designed for: System properties that don't change much.


For your scenario, if you need something that triggers a page refresh, you can implement a polling mechanism that reads a simple table in the DB filtering by a column with an index. It's gonna be fast if the table doesn't grow too much.

If you wanna avoid polling (another good practice), try to use a push mechanism, as for example with this component, or this one.

Hi Ananth,

In the server action if you are getting any response from the Rest API, then Store the response in some table, in the Screen refresh action read the table to get the response, and assign the value to the screen variable.


Thanks

Rajendra Singh 

João Melo wrote:

Hi Ananth.

The issue you're facing must be related to cache propagation between the servers in your Farm. Site Properties use a distribuited cache mechanism in order to gain in performance. So each Site Property has a version of its value on each Application Server. And when you change it, it takes a while to be propagate to all the servers in the Farm.

If you want to force the propagation, you need to use the System Action EspaceInvalidateCache. This way, whenever you change an SP value, it's gonna be propagated to all servers.


BUT!!! It's NOT recommended to keep changing Site Properties. Take a good look at this, this, and this. To briefly summarise, if you change a Site Property value, you're losing its main purpose, which is cache, that leads to performance. Try to use Site Properties with what it's designed for: System properties that don't change much.


For your scenario, if you need something that triggers a page refresh, you can implement a polling mechanism that reads a simple table in the DB filtering by a column with an index. It's gonna be fast if the table doesn't grow too much.

If you wanna avoid polling (another good practice), try to use a push mechanism, as for example with this component, or this one.

Hi João Melo,

Thanks for your reply. I have used the system action  EspaceInvalidateCache after assigning the site variable value. Even then the value is not getting propagated. I would like to use site property for this task now. Please tell if there is any other way to achieve this? Thanks.


Hi Ananth,

You start by saying this:

I have a screen which has to wait for the Site Variable value change. If Site Variable value changes,  then the screen should be refreshed and accordingly values should be displayed in the screen and the process continues.

My question then is how is your screen waiting for the variable to change? How do you know it needs to be refreshed?

Now the problem is Site Variable value is not getting changed after assigning the response in Server action. When I debugged the Server Action, I could see value is getting assigned to the site variable.

So you manage to see the value of the Site Property changing when you are debugging your timer, right?

But When I debugged the screen, I could see only the default value of Site Variable not the changed the value.

How are you debugging your screen? This is the part of your explanation that is not clear to me and could be the missing info to understand what is going on.


Ananth, have you checked your Service Center Error Log? Your logic might be raising an error after Site property assignation, and it can trigger a rollback. If that is happening you will see an error there.

Can you share your Espace?

still why use a site-variable for it?

why not a simple database-record?


J. wrote:

still why use a site-variable for it?

why not a simple database-record?



Hi J,

That server action logic runs in a loop which does not have an end action. so, I am not able to create a record in any entity.

Hi Ananth,

Seems that your approach has some inconsistencies, as highlighted by Jorge Martins, and by youe last comment " That server action logic runs in a loop which does not have an end action. so, I am not able to create a record in any entity.".

Are you able to share screenshots of your implementation?


Cheers,

Tiago.




Tiago Gafeira wrote:

Hi Ananth,

Seems that your approach has some inconsistencies, as highlighted by Jorge Martins, and by youe last comment " That server action logic runs in a loop which does not have an end action. so, I am not able to create a record in any entity.".

Are you able to share screenshots of your implementation?


Cheers,

Tiago.




Please see the screenshot below



It is a long polling logic. See it has no end action. Only if there is any end action, create/update entity action can be done.

Wow! So that's why, Ananth. This is not polling. You're holding a transaction with the DB in that infinite loop. This can be tragical to performance.

When you hold the transaction open, it is not taking into account data changed in other transactions.

You need to end your transaction, and try again, through a new request, every N seconds.

João Melo wrote:

Wow! So that's why, Ananth. This is not polling. You're holding a transaction with the DB in that infinite loop. This can be tragical to performance.

When you hold the transaction open, it is not taking into account data changed in other transactions.

You need to end your transaction, and try again, through a new request, every N seconds.

How can I call this server action every N seconds. Right now, I am triggering this action by a timer. I can only set the minimum time interval as 5 mins only - The server action can be called every 5 mins. How to run the server action every 3 seconds. Please help!


Ananth wrote:

How can I call this server action every N seconds. Right now, I am triggering this action by a timer. I can only set the minimum time interval as 5 mins only - The server action can be called every 5 mins. How to run the server action every 3 seconds. Please help!

You can do it using BPT, using a wait activity to schedule the execution to a specific timestamp. However that's still not the optimal solution. Pooling something every 3 seconds to populate a local database is kind of awkward.

If the WS call is quick enough, I would call it every time the application needs to use the value.


From your web screen, you can create a javascript that triggers a click every N second. But again, think twice. It can be a very bad architectural approach.

João Melo wrote:

From your web screen, you can create a javascript that triggers a click every N second. But again, think twice. It can be a very bad architectural approach.


That is my current implementation :-D

Ananth wrote:

João Melo wrote:

From your web screen, you can create a javascript that triggers a click every N second. But again, think twice. It can be a very bad architectural approach.


That is my current implementation :-D

So why don't you just call the WS then? It is not an optimal solution as it still relies in short interval pooling, but reduces complexity and resource consumption.


Tiago Gafeira wrote:

Ananth wrote:

João Melo wrote:

From your web screen, you can create a javascript that triggers a click every N second. But again, think twice. It can be a very bad architectural approach.


That is my current implementation :-D

So why don't you just call the WS then? It is not an optimal solution as it still relies in short interval pooling, but reduces complexity and resource consumption.


Hi Tiago Gafeira and João Melo,

Now, I have written a javascript that triggers a click every 2 seconds in the Web screen. It works fine and am able to check if I got any new record in the DB. But the problem is after few minutes, I am getting error like "The server went offline because of maintenance. Please try again later" and "Run time error". Why this is happening?

Ideally, It should work right?



Hi Anath,

What is the click triggering? A call to the WS, query to the DB or a Site Property read?

Do you have error messages in Service Center?

Tiago Gafeira wrote:

Hi Anath,

What is the click triggering? A call to the WS, query to the DB or a Site Property read?

Do you have error messages in Service Center?

Query to the DB I am doing. I don't see any error messages in Service Center. :(


Ananth wrote:

Query to the DB I am doing. I don't see any error messages in Service Center. :(


And how are you filling the value in the DB? Still the timer approach?

Tiago Gafeira wrote:

Ananth wrote:

Query to the DB I am doing. I don't see any error messages in Service Center. :(


And how are you filling the value in the DB? Still the timer approach?

I am using Timer just to trigger the Server action to send request to the REST API. Once the I got the response, I am saving the response in a DB as previously suggested by many people. After that, again sending request to the REST API and the process continues. This works fine. No issues. Responses are getting populated in DB as well.

My problem is I have to keep checking if there is any new record in DB and accordingly I will populate the values in the screen. For this only, I am using JavaScript which triggers click ( an action to query DB) on every 2 seconds.

It works fine for sometime and after it throws out error as I previously mentioned.


Do you still have the same implementation has sent in this screenshot but with an update in the DB?



This is really hard in the server and could cause crashes.


Hi Ananth. I agree with the last Tiago's post. It is an infinite loop. So if you're still doing this, you need the change again your strategy.

Otherwise, the error you're getting can be either a huge coincidence or your server has crashed. If you're using the Enterprise cloud or Personal cloud your server can have gone into a maintenance operation while you were testing your app.

But the server is receiving a web request every 2 seconds. Depending on what you're doing in your server logic. It is still very heavy. Can you get access to the IIS server logs?

Hi,


I like that you are trying to find a way to achieve what you want, however.


An infinite loop is bad:

- you are locking the cpu and memory by continiously calling a webservice.

- you are "frustrating" the platform by updating site-variables every time.

- you are flooding IIS, with requests, and the more people accessing that page, the more requests.

- you don't have any killswitch in your code, to prevent the whole bunch locking up, so it's impossible to stop it.

- you are not checking the status of the webservice, just blindly continue with the next..

 


I am sorry, but site-properties are not meant for that what you are trying to achieve.


I am still cluess why it would not be possible to create a record.

simply do a commit after that and you are free to go.


Furthermore, what's the reason why you want to poll a webservice every 2 seconds?