TACC / Lmod

Lmod: An Environment Module System based on Lua, Reads TCL Modules, Supports a Software Hierarchy
http://lmod.readthedocs.org
Other
480 stars 124 forks source link

A Request to have Lmod support the TCL command break. (was issue #90) #143

Open rtmclay opened 8 years ago

rtmclay commented 8 years ago

@hpourreza has requested that Lmod support the TCL command break.

This is a very big change in the internals of Lmod. For example in Tmod, the following happens:

  $ module av
     a/1.0    break/1.0  c/1.0  d/1.0

   $ module load a break c
   $ module list 

The result is that the modules "a" and "c" are loaded and "break" and "d" are not. Note that the "break" module is:

 #%Module
 module load d
 setenv BREAK_VERSION 1.0
 break

The most important part is that the BREAK_VERSION variable IS NOT SET!!!! Also module d is loaded then when the break occurs the actions of d are as if they didn't happen.

This is a huge problem. That means that Lmod would have to somehow roll back the changes that the happen during the evaluation of the module commands.

Also when an env. var is to be set via a "setenv", the setenv command also pushes the env. var to be set in the current environment running under Lmod. This setting may be hard to be reversed. You might be able to clear a env. var. that was set but it will be difficult to return it to its previous value.

UGH!

tjfulle commented 5 years ago

I came here just now to request this feature! I was bit by a TCL module at Sandia that used the break command - at the very least, Lmod could implement break as a call to LmodMessage with a warning, that way the user will be notified of the failed load by Lmod, and not get some cryptic message from tclsh about break being used outside a loop. While I personally find Tmod’s break problematic, it does apparently exist in the wild.

An easy implementation might be to clone the current environment before evaluating a TCL module and restoring it from the clone if break is called. I implemented this idea last night in a python implementation of modules that simply raises an exception if break is called by a TCL module and it seems to work. I didn’t measure the performance implications. The relevant portion of the Python implementation:

try:
    if isinstance(module, pymod.module.TclModule):
        clone = pymod.environ.clone()
    exec_(module.read(), sandbox, {})
except pymod.error.TclModuleBreakError:
    pymod.environ.restore(clone)