short-term persistence across several service calls

I have a service that needs to implement something like like a "session" where several objects are created that are used across several service calls, then disposed when the session ends.

A database is way overkill. It's similar to establishing a session on a web site that lets you visit several web pages that collect data and stash it away, like a shopping cart.

In fact, it's just a couple of stringlists with a handful of strings in them, and an object that's initialized with some data that needs to be used each time the service is called for the given session.

I could reinitialize the object each time, but ... why? It's a lot of needless overhead.

What's the best way to do this with XData other than using a DB?

You can simply use any in-memory structure. Just be sure it's thread-safe and you are ready to go. However, note that this approach is not scalable - you will not be able to use two or more XData servers running to serve your clients.

In case you need scalability and don't want to use the db, you need to use a different distributed storage, like Redis or AWS Elasticache.

Why would an in-memory data structure prevent running multiple XData servers? Certainly, it needs to be threadsafe because of the multi-threaded nature of how services run, but there are at least a handful of ways of dealing with that.

What I meant was multiple distributed XData servers. For example, if you want to do load balancing, you might have a XData server running at one computer, and another XData server running at another computer. Those would be two different executables, and thus would have totally different in-memory data.

Ah, yes, that makes more sense. You'd need an external (to the XData app) shared resource in that case. Which is of course what databases are pretty good at.

1 Like

hmmmm ... it makes me think a different approach might be in order. Here's a scenario: let's say that each time you call this one interface it returns a stringlist that contains a paragraph of text made up of several lines. What I've been thinking is that I'd call it repeatedly to get another paragraph until I'd gotten as many words as needed. Instead I could simply call it once with a parameter that says to return as many paragraphs as needed to fulfill the need; eg, 800 words, 1500 words, whatever. Then the question becomes, can I get back a list of stringlists? I know that JSON can handle it, but can I just return a List-of-TStringlist and have it do what you'd think?

Why don't you return a list of strings? TStringList is, in my opinion, just a wrapper around a string that provides helper functions to work with the string.
But for communication (REST), it's better just to return it as a pure string. The new line characters will be encoded inside the string.

Well, the design is to request these "paragraphs" of text one by one until there are enough for the present needs. Stringlists make it easy to manage the content for what I'm doing. I suppose I could just return a bunch of lines with some kind of separator between paragraphs (double newlines or some flag). It won't matter much to get more than I need; we're talking 10-20 of them ("paragraphs") for each session. The content that's being generated uses a proprietary algorithm that lives inside the service to keep prying eyes from reverse-engineering it. It's kind of like a factory, and the client side requests enough to fill its needs before processing it further.

Actually, perhaps it would be simpler to just generate a couple dozen or so and then compress that data and send it back that way. The client can then just grab as many as it needs and toss the rest away.

Although it looks like stream compression is a middleware option in XData.

No problem. Although I recommend you use TList<string> (or TArray<T>) instead of TStringList, for XData communication.

I changed it to just 'string' but the result is ugly and hard to read. I'll give TList a try and just add one line at a time, see how that works.

1 Like

I changed the return type to TList and I get the same results. The Swagger page shows this. There's a problem somewhere, maybe two; I'm just not sure where. FYI: I'm creating the TListofStrings = TList instance in the service class' constructor, assigning it to the result of the service method, and freeing it in the service class' destructor. I'm guessing that XData gets the data to return and processes it before it calls the object's destructor, but maybe it's using the object itself rather than a copy and the object gets destroyed too quickly? I do get all of the expected data in the "value" tag, but I'm not sure what that "error" is from. Just thinking out loud...

can't parse JSON.  Raw result:

{
    "value": [
        "this is the first of many strings",
        ". . ."
        "and this is the last"
    ]
}{
    "error": {
        "code": "InvalidPointer",
        "message": "Invalid pointer operation"
    }
}

You should not do it, because XData itself destroys the object. There is a topic in the documentation about memory management in XData.

Ahh, yes, thanks for the reminder.

That fixed he problem. Now it's working fine.

Thanks!

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.