epics-modules / autosave

APS BCDA synApps module: autosave
https://epics-modules.github.io/autosave/
Other
8 stars 31 forks source link

make requestfile and macrostring together to identify a unique data set #4

Open xiaoqiangwang opened 8 years ago

xiaoqiangwang commented 8 years ago

The backgroud: I want to define a standard startup script for an epics driver.

  # file st.cmd.dum
  dumAsynPortConfig("DUM$(N=1)")
  dbLoadRecords("dum.db", "P=XW$(N=1):")
  set_pass0_restoreFile("dum_settings$(N=1).sav")
  # afterInit is an iocsh command to run the command after iocInit
  afterInit create_monitor_set("dum_settings.req",10,"P=XW$(N=1):","dum_settings$(N=1).sav")

And then the user script only needs to define macro N and can load the driver multiple times

  # file st.cmd
  < st.cmd.dum
  epicsEnvSet("N","2")
  < st.cmd.dum
  epicsEnvSet("N","3")
  < st.cmd.dum

The current version of autosave would refuse to load the same requestfile twice, even the actual PVs are different because of different macrostring. The proposed change is to make requestfile and macrostring together to identify the data set. Changed(backwards compatible):

Not done(breaks):

keenanlang commented 8 years ago

Looks like a decent solution, though two things to help you out.

The STD epics module has doAfterIocInit that appears to do the same thing as your afterInit function, if you don't want to duplicate work.

And, in EPICS base 3.15 and later, there is the iocshLoad function which is meant to be used to facilitate exactly the kind of standard startup scripts you are describing. Instead of using epicsEnvSet to changes variables every time you want to run the startup script, you'd do:

iocshLoad("st.cmd.dum", "N=1")
iocshLoad("st.cmd.dum", "N=2")

st.cmd.dum would be run by the IOC shell with N as a temporary environment variable that is removed after the script ends.

timmmooney commented 8 years ago

Do you need autosave to maintain separate .sav files for each instance of dum.db, or is this just a way to get the PV values autosaved? If you don't actually need separate .sav files, then autosaveBuild can take care of adding multiple copies of dum_settings.req to auto_settings.req for you, or you could use the autosave function appendToFile() to add lines like the following to auto_settings.req:

file dum_settings.req P=XW1: file dum_settings.req P=XW2:

xiaoqiangwang commented 8 years ago

I did not know about appendToFile command. That would require the auto_settings.req to be emptied on the first load of st.cmd.dum, and the last load of st.cmd.dum to call create_xxx_set. Then it is not anymore stateless.

We had thought of copying the requestfile, but found it hacky. e.g.

# file st.cmd.dum
  copy "dum_settings.req" to "dum_settings$(N=1).req"
  # afterInit is an iocsh command to run the command after iocInit
  afterInit create_monitor_set("dum_settings$(N).req",10,"P=XW$(N=1):")

Most of our EPICS database programmer are not aware of the autosaveBuild option yet. And neither is our EPICS base 3.14 patched to allow this.

timmmooney commented 8 years ago

You could do what autosaveBuild does: clear the file include_settings.req at the beginning of st.cmd, and from then on append lines to that file. If you have the line "file include_settings.req" in auto_settings.req, you'll get everything saved and restored.

The nice thing about your strategy is that it neatly solves the problem of saved PV values being lost if a database is commented out for one or more reboots and then added back in. (Well, not actually lost, but anyway not in the current copy of auto_settings.sav.) The thing that concerns me is the number of save sets that might eventually be created if this becomes your standard practice. On Linux, I think there's likely no real problem. On vxWorks, I would worry about all the file I/O.

timmmooney commented 8 years ago

I talked with Andrew Johnson about whether a large number of save sets would get us into trouble with vxWorks NFS, and that doesn't look like a problem, as long as we don't try to have many open at once. Autosave handles save sets one at a time, so that's not a problem. There is a potential problem for save sets that should be saved frequently having to wait for their turn in a long list. Also, this strategy would of course multiply what is for many beamlines already a large number of files in the autosave directory. We would also have to fix the reload_xxx_set functions, and there's probably some other stuff I've missed.

I can't think of a way to rescue getMacroString() from a strategy that uses macro strings to identify save sets, though. How about if we identify save sets by their save-file names instead of by req-file name and macro string?

xiaoqiangwang commented 8 years ago

The search shows that getMacroString is only used by configMenu subroutine record. https://github.com/epics-modules/autosave/search?utf8=✓&q=getMacroString

Currently the subroutine uses a-g input fields, if in a backwards compatible way, field h is used for macrostring, then getMacroString argument can be made to accept both filename and macrostring.then getMacroString is not anymore required.

timmmooney commented 8 years ago

Yes, but the reason for getMacroString() is that the database has no reliable way of getting the string other than to ask autosave for it.