Sharing Variables on MiServer

MiServer is Dyalog's APL-based web development framework

Sharing Variables on MiServer

Postby Gantois on Wed Nov 16, 2016 6:28 pm

Sharing Variables on MiServer

Hi,
I inicialized one variable in the onSessionStart (:Class MarcoServer : MildServer) reading from a component file. This variable (req.Session.State.hist0101) will be updated by several users in my app. "hist0101" is very big, reason why I am avoiding re-reading it several times from the file after each update. Then, it is being updated on memory too.

My questions are:
1) Is req.Session.State the apropriate local to define it?

2) How could I control the thread? I think I just need my updates to go via a block of code that will be surrounded by a :Hold 'req.Session.State.hist0101' ... :EndHold. Is that right?

3) I observed in my localhost tests that if I make a login (userA) in one browser and make login (UserB) in another browser from the same PC after updated "hist0101" by loginA, this update is not recognized. Is it occurs because I am testing from the same PC? If so, I think it is not a problem but if not, What could I do to control these updates/threads?

Thanks,
Marco

∇ onSessionStart req
:Access Public Override
req.Session.State.hist0101←(⎕new #.fileHist '0101').ReadHist
...
Gantois
 
Posts: 80
Joined: Thu Apr 17, 2014 9:44 am

Re: Sharing Variables on MiServer

Postby Brian|Dyalog on Thu Nov 17, 2016 6:25 pm

To anyone reading this post: Please note that Marco is using MiServer 2.1 and my response is specific to that version of MiServer. The same concepts apply to MiServer 3.0, but in a slightly different format... the primary difference is rather than using the MiServer 2's Render method req argument, in MiServer 3.0 you would use the _Request field in your MiPage.

Hi Marco!

Let's make sure I understand what you're trying to do...
  • hist0101 is a large variable
  • you want one copy of it that several users may update
  • the updates need to be synchronized
If that's the case, then keep reading... :)

The first thing that's important to understand is relationship between the server, sessions, and requests.

Requests
Every time MiServer receives an HTTP Request from the client, it creates an instance of the HTTPRequest class. If session handling is enabled (and it is by default), the request object contains references to a) the user's session - req.Session and b) the server object - req.Server

Sessions
When a user first accesses MiServer, we create a cookie that we then use to identify the user and associate a unique session to that user (and no one else). So, when you reference req.Session, you're accessing something that specific to a single user, not a shared resource.

Server
The server object has a namespace called Application which you can use to hold things that you want to be common and accessible to anything in your application.

Synchronized updates
To make sure that updates to hist0101 are single-threaded, you do need to use :Hold/:EndHold.

So, to accomplish what I think you're trying to do, I'd recommend the following:
  1. In MarcoServer, override the onServerStart method to initialize the shared copy of hist0101:
    Code: Select all
          ∇ onServerStart
            :Access Public Override
            Application.hist0101←(⎕NEW #.fileHist '0101').ReadHist
          ∇
  2. Either in MarcoServer, or your page base class, or your application code, (wherever it makes sense) write an updateHist function that surrounds the update code with :Hold 'hist'/:EndHold. So, for instance, if you were to put it as a method in MarcoServer...
    Code: Select all
          ∇ updateHist args
            :Access Public
            :Hold 'hist'
              Application.hist0101← ... ⍝ do your updates here
            :EndHold
          ∇
  3. Call updateHist from your page(s) as needed using req.Server.updateHist

I hope this helps!
/Brian
User avatar
Brian|Dyalog
 
Posts: 109
Joined: Thu Nov 26, 2009 4:02 pm
Location: West Henrietta, NY

Re: Sharing Variables on MiServer

Postby Gantois on Sun Nov 20, 2016 10:10 pm

Hi Brian.
You clarified exactly what I had doubt. I will apply.
Thanks very much.
Gantois
 
Posts: 80
Joined: Thu Apr 17, 2014 9:44 am

Re: Sharing Variables on MiServer

Postby Gantois on Wed Nov 23, 2016 11:10 am

Hi Brian,

I used your instructions and 'hist0101' variable was updated (very nice), but I have another questions about this. Could you help me?

1. After my app had been started (1 Start 'AppU'), hist0101 variable was not recognized outside the application code (value error). I tried req.Server.Application.hist0101, Server.Application.hist0101, Application.hist0101.(ps:the same occurs when I try Session variables, in other cases)

2. I placed updateHist and others methods using hist0101 var in a class named fileHist (:Class fileHist: MildServer). The same error occurs when I run these methods outside code/page ("hist0101" value error ), for instance:

(⎕new fileHist '0101').displayHist

∇ displayHist
:Access Public
:Hold 'hist'
Application.hist0101
:EndHold


3. Should I use 'hist', 'hist0101', 'Application.hist' or 'Application.hist0101' in the :Hold instruction for this example?

Thanks,
Marco
Gantois
 
Posts: 80
Joined: Thu Apr 17, 2014 9:44 am

Re: Sharing Variables on MiServer

Postby Gantois on Fri Dec 02, 2016 8:34 pm

My question about :hold statment has no sense. Disregard it please.
Thanks,
Marco
Gantois
 
Posts: 80
Joined: Thu Apr 17, 2014 9:44 am


Return to MiServer

Who is online

Users browsing this forum: No registered users and 1 guest