Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saving state #46

Closed
mfornasa opened this issue Sep 25, 2015 · 10 comments
Closed

Saving state #46

mfornasa opened this issue Sep 25, 2015 · 10 comments

Comments

@mfornasa
Copy link

Sorry for the noob questions..
Is there a way to save the state? It seems that when restarting the application the state (topics, variables) is lost. This does not allow for hot upgrades

@kirsle
Copy link
Member

kirsle commented Sep 25, 2015

To export user data to a JSON serializable format, call getUservars() and then to put their variables back in, call setUservars(). You can persist the data however you like (e.g. write JSON files to the hard disk; put them into a SQL database; etc.)

@kirsle kirsle closed this as completed Sep 25, 2015
@mfornasa
Copy link
Author

You are referring to user variables. I'm also interested in conversation status.

For example if the bot says today:

  • do you want to chat?

I want to allow a user to reply tomorrow:

  • sure!

This is not going to work if in the meantime I want to deploy a new version of the bot brain, as this resets the chat history. Is that correct?

This is a real deal beaker if someone wants to maintain the conversation flow for long time periods.

Any idea/suggestion ?

@kirsle
Copy link
Member

kirsle commented Sep 25, 2015

That should still work. Part of the user data includes the recent input and reply history; the reply history is used when processing the %Previous tag, if the bot's next reply should depend on a combination of its previous reply and the user's message. The user's topic is also included in that data (topic is just a specially named user variable; {topic=random} and <set topic=random> both set the same variable, but at different stages of tag processing).

Example output of getUservars():

RiveScript Interpreter (JavaScript) -- Interactive Mode
-------------------------------------------------------
rivescript version: 1.1.4
        Reply root: eg/brain

You are now chatting with the RiveScript bot. Type a message and press Return
to send it. When finished, type '/quit' to exit the program.
Type '/help' for other options.

You> hello bot
Bot> Hi. What seems to be your problem?
You> my name is noah
Bot> Nice to meet you, Noah.
You> how are you?
Bot> Does that question interest you?
You> /log JSON.stringify(bot.getUservars(), null, 2);
{
  "localuser": {
    "topic": "random",
    "__history__": {
      "input": [
        "how are you",
        "my name is noah",
        "hello bot",
        "undefined",
        "undefined",
        "undefined",
        "undefined",
        "undefined",
        "undefined",
        "undefined"
      ],
      "reply": [
        "Does that question interest you?",
        "Nice to meet you, Noah.",
        "Hi. What seems to be your problem?",
        "undefined",
        "undefined",
        "undefined",
        "undefined",
        "undefined",
        "undefined",
        "undefined"
      ]
    },
    "__lastmatch__": "(what|who|when|where|how) [*]",
    "name": "Noah"
  }
}

@mfornasa
Copy link
Author

That should work, thanks.
I suspect that the best approach would be saving the state continuously, to support crashes and external killing of the process. A simpler solution is to do that on startup / shutdown.

@kirsle
Copy link
Member

kirsle commented Sep 25, 2015

That's an exercise for the reader. ;) The library gives you the tools to import/export user variables, but it's up to your actual bot implementation to work out the details of where/when/how to persist them (see scope). For example, some people would be fine with data being saved to disk as JSON files, others would want it to go into a MySQL database instead, then others would want Postgres instead of MySQL, etc., so the library doesn't concern itself with such things.

@mfornasa
Copy link
Author

Thanks for clarifying this.

@mfornasa
Copy link
Author

Can you provide (or point me to) a working get/set user var example?

It's not clear to me what is the purpose of thawUservars, freezeUservars, etc.

@kirsle
Copy link
Member

kirsle commented Sep 28, 2015

I don't have a Node example, but here's a couple examples of doing the same thing in Perl:

The basic logic is:

  1. Before getting a reply for the user, load the user's variables from disk (from a JSON file) if the file exists (it's created in step 3 the first time).
    1. If the JSON file existed, call setUservars(username, data) to set all the variables in the bot's memory.
  2. Get a reply for the user like normal.
  3. Use getUservars(username) to get all their variables, and write the JSON.stringify() output into a JSON text file on disk. On the next reply, the file exists now so on Step 1 it's read back from disk and reinserted into the bot's memory.

The freezeUservars() and thawUservars() functions are for snapshotting and backing up the user's variables. It's useful if you wanted to "test" a reply but don't want any side effects from it (such as changing of any user variables). Example of that:

rs.reply("user", "my name is alice");
console.log(rs.getUservar("user", "name")); // "Alice"

rs.freezeUservars("user");

rs.reply("user", "my name is bob");
console.log(rs.getUservar("user", "name")); // "Bob"

rs.thawUservars("user", "thaw");

console.log(rs.getUservar("user", "name")); // "Alice" again.

kirsle added a commit that referenced this issue Sep 28, 2015
@kirsle
Copy link
Member

kirsle commented Sep 28, 2015

I've added an example of persisting user data to disk as JSON files to the rivescript-js examples directory:

https://github.com/aichaos/rivescript-js/tree/master/eg/persistence

@mfornasa
Copy link
Author

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants