2

I have a library of stored compiled macros, i.e. macros that I define like this :

options mstored sasmstore=MYLIB;

%macro say_something(txt) / STORE SOURCE;
%put &txt;
%mend;

I'm often getting this error message :

NOTE: The SAS System was unable to open the macro library referenced by the SASMSTORE = libref MYLIB.

ERROR: A lock is not available for MYLIB.SASMACR.CATALOG.

ERROR: Lock held by process 4653302.

ERROR: A dummy macro will be compiled.

It happens when I try to define a macro (e.g. execute above code) and I believe it happens in 2 circumstances:

  1. Another session is opened where a macro has already been defined.

  2. Another session is opened where a process is currently running, using a macro from my library

(It's not all clear to me though)

Can I avoid this ?

In the first case I'd like to give up the writing rights so another session can take them. I currently do it by closing the file and reopening it, which is tedious and very annoying if by mistake I started a long process on this file before "rebooting" it.

In the 2nd case I don't really get why the lock would happen as I'm barely using a macro, not writing anything to the library. As my library will be used by more people I'll need to find the "right time" to commit, which is really not the clean workflow I'm looking for.

Community
  • 1
  • 1
moodymudskipper
  • 46,417
  • 11
  • 121
  • 167
  • Are you trying to update the macro catalog while it is actively being used? Can you shut down all usage while you make the updates to your macro catalog? – Tom Jun 05 '18 at 14:50
  • 1st question: yes, 2nd question: mostly no but yes for case 1 when I know I'm the only one working on it, and there's just one session locking everything for "no good reason". – moodymudskipper Jun 05 '18 at 15:05

2 Answers2

4

My suggestion would be to stop using stored compiled macros and use an autocall macro folder instead, using the sasautos option. You can then make changes at any time without worrying about locks. Any sessions already running will need to re-load the macro in order to pick up the new definition.

user667489
  • 9,501
  • 2
  • 24
  • 35
  • Maybe... The issue is that as I understand it I'll need to have one file per function, and put these files on server side, so I only have SAS EG to run SAS, no SAS Studio, so it's already tedious, and I haven't figured out how to design a nice workflow with autocall macros... – moodymudskipper Jun 05 '18 at 09:26
  • A hack would be to fetch all the code from the catalog, remove the `/ STORE SOURCE DES =*?;` with regex, and execute it. So in my startup code I'd have `options mstored sasmstore=MYLIB; %fetch_macros(MYLIB)`. This would also provide a hack for this: https://stackoverflow.com/questions/50599792/automatic-parameter-and-definition-display-for-macro-functions-in-sas-eg – moodymudskipper Jun 05 '18 at 09:26
  • You can have multiple macro definitions in the same file in an autocall folder. As long as one of these has the same name as the file, all the others will be compiled when you call that one. – user667489 Jun 05 '18 at 13:47
4

Some of this might require a different workflow, but it's probably the "right" workflow.

Particularly (2). You shouldn't be writing to the macro catalog that your coworkers are reading from. Rather, you should be writing to a local macro catalog, that you then periodically commit to source control (or, if you are doing "manual" source control, that you periodically copy up to the production location). That also allows for proper testing before deployment. Here, periodically probably means "once a day", or less, depending on your development cycle.

Otherwise, you may make a change to a macro that a coworker is using, and they may not appreciate that change, or may not know if they ran the before-change or after-change version of the macro - which is just as bad.

This would also to a large extent prevent (1); if each SAS session only writes to a local copy (to that session, or to the user), then you shouldn't have too many instances where you're conflicting. You could have two instances of SAS open yourself of course writing to the same one, but that's something you should simply avoid.

Joe
  • 62,789
  • 6
  • 49
  • 67
  • This is indeed a good way of dealing with 2, I'd still have to make everyone reboot their session if I need to commit a macro "urgently", which is not ideal. I agree with your last sentence and I'm trying hard to do it this way, but in a job where you have queries running you always end up multitasking, and sometimes it's on macros. Maybe I could have several development libraries, but I can only use one at a time in a given session right ? – moodymudskipper Jun 05 '18 at 15:12
  • Well, you don't have to store the macros while you're doing development, do you? Can't you just run them as regular plain old macros until you're satisfied with the changes? – Joe Jun 05 '18 at 15:33
  • I do this sometimes, but I have to comment/uncomment these `/ STORE SOURCE DES='...'` and rerun them once uncommented, it seems suboptimal, I'd rather have them in a development library and run a macro `%commit(my_macro1 my_macro2,from=devlib,to=prodlib)` – moodymudskipper Jun 05 '18 at 15:37