Please add ability to change from pause to finish

Moderators: Site Moderators, FAHC Science Team

calxalot
Site Moderator
Posts: 1476
Joined: Sat Dec 08, 2007 1:33 am
Location: San Francisco, CA
Contact:

Re: Please add ability to change from pause to finish

Post by calxalot »

Some informal documentation is in client discussions, particularly
https://github.com/FoldingAtHome/fah-cl ... ssions/215

Other than that, there is the web control source code, and watching the JavaScript console in your browser while using web control.
calxalot
Site Moderator
Posts: 1476
Joined: Sat Dec 08, 2007 1:33 am
Location: San Francisco, CA
Contact:

Re: Please add ability to change from pause to finish

Post by calxalot »

If you can read python, there is my sloppy code
https://github.com/kbernhagen/lufah
calxalot
Site Moderator
Posts: 1476
Joined: Sat Dec 08, 2007 1:33 am
Location: San Francisco, CA
Contact:

Re: Please add ability to change from pause to finish

Post by calxalot »

arisu
Posts: 373
Joined: Mon Feb 24, 2025 11:11 pm

Re: Please add ability to change from pause to finish

Post by arisu »

TheMikeyDK wrote: Fri May 02, 2025 6:35 pm
calxalot wrote: Thu Apr 24, 2025 9:36 pm Sorta. It sends commands to clients using the undocumented api that web control uses. It doesn’t login to an account or use the node system.
How undocumented is it? Is it possible to somehow find some information about that?
Completely undocumented but not at all secret. All of the API is handled by a single 190 line C++ file which is open source in src/fah/client/Remote.cpp.

The websocket communicates using JSON. Here is a simple Python function that lets you send commands via the websocket:

Code: Select all

import websocket, json

def sendcmd(cmd, arg):
    ws = websocket.create_connection('ws://localhost:7396/api/websocket')
    ws.send(json.dumps({'cmd': cmd, cmd: arg}))
    ws.close()
The format for commands is pretty simple. To change the state, the "cmd" key is set to "state" and then the "state" key is set to whatever the new state is (finish, pause, or fold). If you wanted to change the config instead, then the "cmd" key would be set to "config" and you'd have a "config" key (instead of a "state" key) set to whatever the new config is.

Here are a few examples of JSON you could send. To pause all units:

Code: Select all

{
  "cmd": "state",
  "state": "pause"
}
To change the config is slightly more complex if you don't know JSON. Here's an example changing the number of available CPUs to 6 and turn on beta on the default group (group "" aka an empty string), and turning off beta but turning on folding on battery for a group called "mygroup":

Code: Select all

{
  "cmd": "config",
  "config": {
    "groups": {
      "": {
        "cpus": 6,
        "beta": true
      },
      "mygroup": {
        "on_battery": false,
        "beta": false
      }
    }
  }
}
But this is still basically the same as the others, being {"cmd": "config", "config": configGoesHere} except that configGoesHere is not just a string.
Last edited by arisu on Sat May 03, 2025 4:06 am, edited 1 time in total.
arisu
Posts: 373
Joined: Mon Feb 24, 2025 11:11 pm

Re: Please add ability to change from pause to finish

Post by arisu »

OP, the solution to your problem is to send a config command instead a state command. Here's a super simple Python script that will change the state from pause to finish atomically (without first going through fold). The script takes one optional argument which is the group name. If no argument is given, it will apply to the default group:

Code: Select all

#!/usr/bin/python3

import sys, json, websocket

HOST = 'localhost'
PORT = '7396'

try:
    GROUP = sys.argv[1]
except KeyError:
    GROUP = ''

ws = websocket.create_connection(f'ws://{HOST}:{PORT}/api/websocket')
state = json.loads(ws.recv())
groups = dict.fromkeys(state['groups'], {})

if state['info']['version'] != '8.4.9':
    sys.exit('unsupported client version')

if GROUP not in groups:
    sys.exit(f'group {GROUP} does not exist')

groups.update({GROUP: {'finish': True, 'paused': False}})
ws.send(json.dumps({'cmd': 'config', 'config': {'groups': groups}}))
ws.close()
Last edited by arisu on Sun May 04, 2025 6:15 am, edited 3 times in total.
calxalot
Site Moderator
Posts: 1476
Joined: Sat Dec 08, 2007 1:33 am
Location: San Francisco, CA
Contact:

Re: Please add ability to change from pause to finish

Post by calxalot »

The dump command requires the uuid of the unit.

The config command must contain at least an empty dict for every group.
Not including a group will cause it to be deleted.
Adding an unknown group will create it.

I believe it is this way for the convenience of coding web control.
calxalot
Site Moderator
Posts: 1476
Joined: Sat Dec 08, 2007 1:33 am
Location: San Francisco, CA
Contact:

Re: Please add ability to change from pause to finish

Post by calxalot »

I’m pretty sure the client doesn’t support going from pause straight to running with finish.
calxalot
Site Moderator
Posts: 1476
Joined: Sat Dec 08, 2007 1:33 am
Location: San Francisco, CA
Contact:

Re: Please add ability to change from pause to finish

Post by calxalot »

You absolutely should not manipulate the pause and finish flags on a group. They are internal state flags, not valid configuration items.

Even if it works there could be bad side effects and it may break in the future.

You should use the pause, fold, and finish commands.
arisu
Posts: 373
Joined: Mon Feb 24, 2025 11:11 pm

Re: Please add ability to change from pause to finish

Post by arisu »

It does support going straight to pause to finish but only if you adjust the state. I checked the code and directly adjusting the pause and finish flags is exactly what using the state command does (see Config::setState() in src/fah/client/Config.cpp). There are no side-effects.

Good point that it might break in the future although it looks unlikely based on the code. But I didn't even think about that. I'll edit my script to add a check for the current version as a safety guardrail.
calxalot
Site Moderator
Posts: 1476
Joined: Sat Dec 08, 2007 1:33 am
Location: San Francisco, CA
Contact:

Re: Please add ability to change from pause to finish

Post by calxalot »

Interesting. I don’t expect it to be part of the official api. Maybe the semantics of the finish command will be changed to do this.

Your dump command would need to get the uuid for the unit at the adjusted index.
arisu
Posts: 373
Joined: Mon Feb 24, 2025 11:11 pm

Re: Please add ability to change from pause to finish

Post by arisu »

Since those were just examples it was easier for me to just remove that dump example.

The state command runs app.setState(state) which will run setPaused(false) if state == "fold", setPaused(true) if state == "pause", or insertBoolean("finish", true) if state == "finish". But the setPaused() function runs insertBoolean("finish", false) no matter what value it is passed, which is why it's currently not directly possible to change the pause state without simultaneously unsetting the finish flag. I think this is done to clear the finish flag so people aren't confused by clicking "fold" (which just runs setPaused(false)) and seeing the state change to finish. It just aligns the client's behavior with the mental model that users have of its UI, ie users think fold means "start folding" when OP wants it to mean "set paused to false, but don't touch the finish flag".

The whole issue stems from any call to setPaused() unsetting the finish flag.

The script I posted just bypasses setPaused() completely and directly changes the state. There are no sanity checks done and you could probably send {"finish": "foo"} which would change it to an invalid state. What happens then depends on how getBoolean() is defined in cbang which I haven't checked.
calxalot
Site Moderator
Posts: 1476
Joined: Sat Dec 08, 2007 1:33 am
Location: San Francisco, CA
Contact:

Re: Please add ability to change from pause to finish

Post by calxalot »

I’m sure the client needs more rigorous checks on input.

Do you think I should change lufah to support pause to finish? Maybe with a force flag?
calxalot
Site Moderator
Posts: 1476
Joined: Sat Dec 08, 2007 1:33 am
Location: San Francisco, CA
Contact:

Re: Please add ability to change from pause to finish

Post by calxalot »

What happens if you set paused false, finish true on a group that is paused and has no units? Is a new WU started? That would seem undesirable.
arisu
Posts: 373
Joined: Mon Feb 24, 2025 11:11 pm

Re: Please add ability to change from pause to finish

Post by arisu »

If paused is set to false, then it will try to download a new unit no matter what the value of finish is. And you can't override that using just the state command because going from paused to fold will, annoyingly, clear the finish flag.

I think it would be fine for lufah to have that feature although first it should be tested with a client in several states. For example, everything I described and tested happens when a unit is in the UNIT_RUN state (which can be paused, folding, finished or whatever, it just means the unit is ready). But I have no idea what happens if you directly change the config to unpause a unit that is in some different state like UNIT_DUMP or UNIT_CORE. Although you could just check that it's in UNIT_RUN before performing the action.

Btw another possible way to do this using more "standard" parts of the API (only using API features that the web client also uses) would be taking the resources away from the units, i.e. setting CPUs to 0 and removing any GPU, then setting the state from paused to fold the normal way, then set the state to finish, then give the resources back. I haven't tested it but that might also move the units from pause to finish without putting all of them in a runnable state at any point in time (which would cause a finished unit to begin its download).

Honestly none of this would be an issue if "resource groups" were more ergonomic (I never recommend random people use them because the FAQ even warns that it is for experts only), or if you could change the state of individual units. The dev is insistent that there's no need for that ability because you can "just use resource groups", but resource groups come with a whole can of caveats that break the mental model people have of the program.
calxalot
Site Moderator
Posts: 1476
Joined: Sat Dec 08, 2007 1:33 am
Location: San Francisco, CA
Contact:

Re: Please add ability to change from pause to finish

Post by calxalot »

BTW, your example deletes all groups except the targeted one. You need an empty dict for every other group in the config group command.
Post Reply