19.0.0 released Nov 08, 2023
Global process data

The purpose of global-process data is to help with use of global cross-request variable(s) anywhere in your code. The difference from global-request-data is in the scope: global request data is valid only for a single request, while global-process data is valid for all requests processed in sequence by a single process (see how-vely-works).

While you can create global variables in C (with C's "extern" to make them globally available), Vely's global-process data is an easier and more structured way to share data globally across requests. This way, you do not have to define and maintain global variables. It also makes it more maintainable as such variables are well-encapsulated and easy to track (for instance in code reviews).
What is global-process data
Global-process data is a generic pointer (void*) that points to any memory you wish to be shared among all your code across all the requests that any given process serves. This data cannot be shared between different processes. It is usually a structure containing information globally pertinent to your application that is shared between separate requests. The pointer's scope is a lifetime of the process and thus spans all the requests it serves. The global-process data pointer is initialized to NULL before startup-handler executes. It is stored in Vely's internal process context structure so it can be used anywhere.
Setting
set-app process-data <data>

where <data> is a pointer to any memory you wish to use anywhere in your code across all process' requests. This memory must be unmanaged; see memory-handling and the example below.
Getting
Global-process data can be obtained anywhere in your code with:
get-app process-data to <data>

where <data> is a pointer to any type.
Usage
Typically you would define a structure or a typedef that encapsulates any data that needs to be shared throughout your code in all requests in any given process. Different processes have separate process data that cannot be shared between them. For this reason, global-process data is not the same as global application data; rather it is global within any given process and not beyond that process.

In startup-handler, you would create a variable (or an array) of this type by using unmanaged new-mem that producess cross-request memory - this is done by using "off" clause in manage-memory. Use new-mem for any members that need allocating. Initialize anything that needs it. Finally, switch back to managed memory by using "on" clause in manage-memory statement.

The reason for using unmanaged memory is because otherwise the data would be automatically released at the end of the following request and would not stay allocated for the life of the process.

Next, save the pointer to the variable (or an array) you created by using set-app.

Finally, anywhere you need to set or get any data, use get-app with "process-data" clause to get the pointer and manipulate or read your global-process data. Don't forget that any manipulation must be in unmanaged mode as well.
Examples
Suppose your application has an include file my.h in which you define type "procdata":
#ifndef _MY
#define _MY

typedef struct s_procdata {
    bool some_flag;
    bool another_flag;
    char *ptr;
} procdata;

#endif

Your startup-handler (i.e. file _startup.vely) might look like this - note that my.h is included, providing your type definition "procdata":
#include "vely.h"
#include "my.h"

void _startup () {
    procdata *rd; // A pointer to global request data

    // Use unmanaged memory for process-wide data
    manage-memory off
    // Allocate global request data
    new-mem rd size sizeof(procdata)
    // Turn back on managed memory
    manage-memory on

    // Initialize values in it
    rd->some_flag = false;
    rd->another_flag = false;

    // Save the pointer so you can use it anywhere with get-req
    set-app process-data rd
}

In the above code, a new pointer "rd" of type "procdata" is created with new-mem. Data initialization takes place - anything that needs initialization should be initialized. Finally, pointer "rd" is saved to process' internal structure with set-app, so it can be used in any request for the life of the process.

In your code, wherever it's needed, you can obtain this data into a local pointer of the same type "procdata" (in this case pointer name is "mydata"). You can do that with get-app and then examine or set any global-process variable you wish:
#include "vely.h"
#include "my.h"

request-handler /mycode

    ...
    procdata *mydata; // declare local pointer 

    // get the actual value of a pointer, so now it points to global request data
    get-app process-data to mydata

    // do whatever you want with the data: examine, set etc.
    if (mydata->another_flag) {
        mydata->some_flag = true;
        // If you free, allocate or reallocate global-process data, use unmanaged memory
        manage-memory off
        resize-mem my_data->ptr size 1024
        manage-memory on
    }
end-request-handler

See also
Process
global-process-data    
See all
documentation


You are free to copy, redistribute and adapt this web page (even commercially), as long as you give credit and provide a dofollow link back to this page - see full license at CC-BY-4.0. Copyright (c) 2019-2023 Dasoftver LLC. Vely and elephant logo are trademarks of Dasoftver LLC. The software and information on this web site are provided "AS IS" and without any warranties or guarantees of any kind. Icons from table-icons.io copyright PaweĊ‚ Kuna, licensed under MIT license.