I am trying to add a Mandatory field option for the argument in my dart script. I am using addOption() as visible in the code below. and to run the code in the terminal.
$dart args_demo.dart -h
If I run the code without mandatory: true in the method addOption(), I get no error and a help text is shown, everything works fine.
But, when I add this part mandatory: true in the method addOption(), and run the script with above command, I get this error massage
Unhandled exception:
FormatException: Option name is mandatory.
#0 Parser.parse.<anonymous closure> (package:args/src/parser.dart:101:9)
#1 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:397:8)
#2 MapView.forEach (dart:collection/maps.dart:342:10)
#3 Parser.parse (package:args/src/parser.dart:95:22)
#4 ArgParser.parse (package:args/src/arg_parser.dart:335:42)
#5 main (file:///home/penguine/Desktop/codeTesting/argPackage/args_demo.dart:12:26)
#6 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:281:32)
#7 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
Please explain how can I use the mandatory field without getting error.
thanks in advance.
import 'dart:io';
import 'package:args/args.dart';
void main(List<String> args){
final parser = ArgParser()
..addSeparator('===options and flags and help===')
..addOption('name', abbr: 'n', help: 'Provide your name', mandatory: true)
..addFlag('help', abbr: 'h', help: 'Provide usage instruction', negatable: false)
..addOption('paas', help: 'what is your favorite PaaS', allowed: ['AWS', 'GCP', 'Heroku', 'MSA'], defaultsTo: 'GCP');
final results = parser.parse(args);
//print(results);
if (results.wasParsed('help')){
print(parser.usage);
exit(0);
}
if (results.wasParsed('name')) {
print('=>> ${results['name']}');
}
print('PAAS =>> ${results['paas']}');
}
Note that there is nothing special about the -h/--help option itself. It is a boolean flag like any other. Consequently, since you've made -n/--name mandatory, it is exactly that: it is always required, even if you're just trying to print usage text.
The way that -h/--help is handled provides its own clue how you can make an option conditionally required: check ArgResults.wasParsed() and explicitly fail if it's not provided:
final results = parser.parse(args);
if (results.wasParsed('help')){
print(parser.usage);
exit(0);
}
if (!results.wasParsed('name')) {
stderr.writeln('--name is required.');
exit(1);
}
I agree that this behavior makes mandatory: true not very useful. It's a relatively recent addition to package:args, and I've filed https://github.com/dart-lang/args/issues/194.
Consider the following:
#r #"FakeLib.dll"
open Fake
open Fake.StringHelper
open Fake.ProcessHelper
Shell.Exec("mkdir","exampleDirectory")
Target "DoStuff" ( fun () ->
trace "Doing Stuff..."
)
Target "Clean" ( fun () ->
trace "Cleaning..."
)
Target "Deploy" (fun () ->
trace "Deploying..."
)
"DoStuff"
==>"Clean"
==>"Deploy"
RunTargetOrDefault "Deploy"
The above script works fine, but when I move the Shell.Exec within a Target like this:
#r #"FakeLib.dll"
open Fake
open Fake.StringHelper
open Fake.ProcessHelper
Target "DoStuff" ( fun () ->
trace "Doing Stuff..."
Shell.Exec("mkdir","exampleDirectory")
)
Target "Clean" ( fun () ->
trace "Cleaning..."
)
Target "Deploy" (fun () ->
trace "Deploying..."
)
"DoStuff"
==>"Clean"
==>"Deploy"
RunTargetOrDefault "Deploy"
I end up with a an error:
FsiEvaluationException:
Error:
DeployScript.fsx(10,5): error FS0001: This expression was expected to have type
unit
but here has type
int
Output: [Loading C:\Users\myusername\Desktop\SomeFolder\DeployScript.fsx]
Input: C:\Users\myusername\Desktop\SomeFolder\DeployScript.fsx
\Arguments:
C:\fsi.exe
Exception: Yaaf.FSharp.Scripting.FsiEvaluationException: Error while compiling or executing fsharp snippet. ---> System.Exception: Operation failed. The error text has been print the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing
at Microsoft.FSharp.Compiler.Interactive.Shell.FsiEvaluationSession.commitResult[a,b](FSharpChoice`2 res)
at Microsoft.FSharp.Compiler.Interactive.Shell.FsiEvaluationSession.EvalScript(String filePath)
at Yaaf.FSharp.Scripting.Helper.evalScript#1303.Invoke(String arg00) in C:\code\fake\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1303
at Yaaf.FSharp.Scripting.Helper.save_#1276-2.Invoke(Unit unitVar0) in C:\code\fake\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1277
at Yaaf.FSharp.Scripting.Helper.consoleCapture[a](TextWriter out, TextWriter err, FSharpFunc`2 f) in C:\code\fake\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1221
at Yaaf.FSharp.Scripting.Helper.redirectOut#1247[a](Boolean preventStdOut, OutStreamHelper out, OutStreamHelper err, FSharpFunc`2 f) in C:\code\fake\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1254
at Yaaf.FSharp.Scripting.Helper.save_#1275-1.Invoke(String text) in C:\code\fake\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1276
--- End of inner exception stack trace ---
at Yaaf.FSharp.Scripting.Helper.save_#1275-1.Invoke(String text) in C:\code\fake\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1284
at Yaaf.FSharp.Scripting.Helper.session#1306.Yaaf-FSharp-Scripting-IFsiSession-EvalScriptWithOutput(String ) in C:\code\fake\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1308
at Fake.FSIHelper.runScriptUncached(Boolean useCache, String scriptPath, IEnumerable`1 fsiOptions, Boolean printDetails, CacheInfo cacheInfo, TextWriter out, TextWriter err) in C:\code\fake\src\app\FakeLib\FSIHelper.fs:line 471
DeployScript.fsx(10,5): error FS0001: This expression was expected to have type
The point here is I'm trying to do a shell command only under a certain target. Pay no attention to the mkdir command as I actually would like to use the schtasks command. I just used mkdir for simplicity purposes. Maybe there's a nuance that I'm missing here. I've also noticed this same behavior with using environVarOrFail. Thanks in advance to all who reply.
Shell.Exec returns an int, but Target expects a function that returns a unit.
Try this:
let returnUnit() = ()
let return42() = 42
Target "One" returnUnit // works
Target "Two" return42 // fails: expected to have type unit, but here has type int
The target "Two" fails to compile, because its second argument is a function that returns an int, whereas a function returning unit is expected.
This error is there to keep you from forgetting function return values: the compiler helpfully tells you "Hey, are you sure you don't want to do anything with this int? Then why did you call the function in the first place?"
Sometimes, however, it makes sense to throw away the return value. For example, in this particular case, you're calling Shell.Exec for its side effect, and its return value does not interest you. This situation occurs surprisingly often, so often that there is a special function for it - ignore.
Target "DoStuff" ( fun () ->
trace "Doing Stuff..."
Shell.Exec("mkdir","exampleDirectory") |> ignore // compiles fine
)
This function takes any value, throws it away, and returns a unit. By applying it to the result of Shell.Exec, you tell the compiler: "Yes, I'm sure I don't need this value, please ignore it."
That said, I would strongly recommend using specialized functions instead of generic system calls. This will make your script more readable, and might even help you catch an occasional error early. For example, to create a directory, use FileUtils.mkdir:
Target "DoStuff" ( fun () ->
trace "Doing Stuff..."
FileUtils.mkdir "exampleDirectory" // no need for `ignore`, mkdir already returns `unit`
)
This query is to get the art of validating a stack in general. Below is an example of the problem which may help while giving some ideas.
I am dealing with a MIPS core dump, whose partial stack trace is below.
#2 0x7772027c in __assert13 (file=<optimized out>, line=<optimized out>, function=<optimized out>, failedexpr=<optimized out>) at /work.local/build/toolSpaces/tools01/E9-3-0/SW-NetBSD5/usr/src/lib/libc_r/../libc/gen/assert.c:61
#3 0x773baf3c in f10IpcSendWait (key=0x8f08, payload=0x76d9e318 "", len=0x274, tmout=0x3c, type=0xaf1, transaction=0xc0f) at f10IpcLib.c:2412
#4 0x77391d04 in cfgIpcSendWait (pkey=<optimized out>, cmdType=0x69, data=0x76d9e7a0, len=0x224, retStatus=<optimized out>) at f10CfgLib.c:751
#5 0x77391fc0 in f10CfgGetExact (pkey=0x1, usrData=0x784bb040) at f10CfgLib.c:554
#6 0x1002785c in f10GetBanner (pKey=0x8f08, bannerType=<optimized out>, sessionType=<optimized out>, sessionId=<optimized out>, bannerString=0x77b33000 <Address 0x77b33000 out of bounds>) at pamBannerHandler.c:123
#7 0x10040e40 in sshGetAuthBanner (banner=0x77b33000 <Address 0x77b33000 out of bounds>) at sshPamUtils.c:74
#8 0x10015b80 in userauth_banner () at auth2.c:176
#9 input_userauth_request (type=<optimized out>, seq=<optimized out>, ctxt=<optimized out>) at auth2.c:303
#10 0x76edbea0 in dispatch_run (mode=0x0, done=0x784bbb40, ctxt=0x784bb040) at dispatch.c:98
Here userauth_banner() calls sshGetAuthBanner () with a parameter 0x77b33000. However, when I look into the local variable banner of userauth_banner() it shows me absolutely different value.
(gdb) p banner
$20 = 0x1 <Address 0x1 out of bounds>
I understand that RISC parameters can be passed on stack - but what I can't get is how GDB shows the parameter as 0x77b33000. I guess that it is parameter of some other function called after sshGetAuthBanner() or a result of some other calculation or operation.
userauth_banner(void)
{
char *banner = NULL;
if ((banner = (char *)xcalloc(2, 25600)) == NULL)
goto done;
sshGetAuthBanner(banner);
if (!strlen(banner))
goto done;
So, in all I want to understand, what should we look for, to ascertain if a stack is correct. Also, which value in the case discussed above is more reliable and why.
Any pointers will be helpful.
Here's a simplified version of the code where I get an error that is logged even if the generated HTML looks good. What does this exception means ? Why do I get it ?
index.html :
<!DOCTYPE html>
<div ng-app main>
<div ng-repeat="a in ctrl.listOfA">
<strong>{{ a }}</strong>
<div ng-repeat="b in ctrl.listOfB(a)">
{{ b }}
</div>
</div>
</div>
<script type="application/dart" src="main.dart"></script>
<script src="packages/browser/dart.js"></script>
main.dart :
import 'package:angular/angular.dart'; /* 0.9.10 */
#NgController(selector: '[main]', publishAs: 'ctrl')
class MainController {
final listOfA = new List.generate(2, (i) => 'a$i');
listOfB(a) => new List.generate(2, (i) => 'b$i').map((e) => '$a-$e');
}
void main() {
ngBootstrap(module: new Module()
..type(MainController)
);
}
The logged error :
Observer reaction functions should not change model.
These watch changes were detected: ctrl.listOfB(a): (a0-b0, a0-b1) <= (a0-b0, a0-b1); ctrl.listOfB(a): (a1-b0, a1-b1) <= (a1-b0, a1-b1)
These observe changes were detected:
STACKTRACE:
#0 RootScope.flush.<anonymous closure> (package:angular/core/scope.dart:554:11)
#1 RootScope.flush (package:angular/core/scope.dart:560:9)
#2 RootScope.flush (package:angular/core/scope.dart:561:7)
#3 RootScope.flush (package:angular/core/scope.dart:561:7)
#4 apply (package:angular/core/scope.dart:262:18)
#5 _rootRun (dart:async/zone.dart:710)
#6 _rootRun (dart:async/zone.dart:711)
#7 _rootRun (dart:async/zone.dart:711)
#8 _ZoneDelegate.run (dart:async/zone.dart:440)
#9 NgZone._finishTurn (package:angular/core/zone.dart:96:21)
#10 NgZone._onRunBase (package:angular/core/zone.dart:61:43)
#11 _onRun (package:angular/core/zone.dart:66:15)
#12 _ZoneDelegate.run (dart:async/zone.dart:440)
#13 _CustomizedZone.run (dart:async/zone.dart:650)
#14 NgZone.run (package:angular/core/zone.dart:148:35)
#15 ngBootstrap (package:angular/bootstrap.dart:92:18)
#16 main (http://127.0.0.1:3030/xxxx/web/test/main.dart:13:14)
Angular only supports pure functions in expressions. I guess this started with 0.9.10 because there already was a similar question recently where it stopped working after the update.
ctrl.listOfB(a)
should always return the same result for the same argument,
or even if the result is the same, the cause could be that ctrl.listOfB(a) always returns a new instance of the same result. Angular 0.9.10 doesn't like this either.
It repeatedly evaluates the expression and if it receives a new result each time it throws.
I think the solution is to cache the results and return from the cache if already available.
I have debugged this program for 2 weeks. It has just 93 lines. But I still cannot find the bug. Please help me.
This program is OK on my laptop. But it stuck when I run it on the cluster of my lab, Shanghai super-computing center China and Jinan super-computing center China.
The logic of this program is very simple. There are 2 MPI processes. One is master (pid = 0),the other is slave(pid = 1). Master waits for requests on tag = 0. Slave sends message to master tag:0 every second and wait for ACK message. Once the master get a request, master will send an ACK message to slave tag:100.
The problem is that after a few seconds the program will stuck. Master will stuck at MPI_Recv, waiting for a request on tag:0. Slave will stuck at MPI_Ssend, trying to send a message to master tag:0.
This MPI communication should match each other. But I don't know why it stuck.
Some hints:
Program will not get stuck on the following situations:
1.Adding a sleep() function after pthread_create(&tid,&attr,master_server_handler,NULL); in the void *master_server(void *null_arg) function.
Or
2.Using joinable pthread attribute instead of detachable attribute to create master_server_handler. (pthread_create(&tid,&attr,master_server_handler,NULL); replaced it with pthread_create(&tid,NULL,master_server_handler,NULL); )
Or
3.Using master_server_handler function instead of pthread_create(&tid,&attr,master_server_handler,NULL);.
Or
4.Replacing MPI_Ssend in void *master_server_handler(void *arg) with MPI_Send.
The program is OK under each of these situations.
All these modifications can be found in the notes of the program.
I don't know why it will stuck. I tried openmpi and mpich2. The program will stuck on both of them.
Any hints please...
I can provide VPN of my lab if it is needed. You can log in the cluster in my lab.
(e-mail:674322022#qq.com)
BTW:
I enabled the parameter of threads supporting while compiling openmpi and mpich2. For openmpi the parameter is --with-threads=poxis --enable-mpi-thread-multiple. Mpich2 is --enable-threads.
Machines in my lab is CentOS. Out put of uname -a is Linux node5 2.6.18-238.12.1.el5xen #1 SMP Tue May 31 14:02:29 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux.
I run the program using: mpiexec -n 2 ./a.out
Following are the source code, out put of the program, the back-trace info when the program stuck.
Source code
#include "stdio.h"
#include "pthread.h"
#include "stdlib.h"
#include "string.h"
#include "mpi.h"
void send_heart_beat();
void *heart_beat_daemon(void *null_arg);
void *master_server(void *null_arg);
void *master_server_handler(void *arg);
int main(int argc,char *argv[])
{
int p,id;
pthread_t tid;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&p);
MPI_Comm_rank(MPI_COMM_WORLD,&id);
if(id==0)
{
//master
pthread_create(&tid,NULL,master_server,NULL);
pthread_join(tid,NULL);
}
else
{
//slave
pthread_create(&tid,NULL,heart_beat_daemon,NULL);
pthread_join(tid,NULL);
}
MPI_Finalize();
return 0;
}
void *heart_beat_daemon(void *null_arg)
{
while(1)
{
sleep(1);
send_heart_beat();
}
}
void send_heart_beat()
{
char send_msg[5];
char ack_msg[5];
strcpy(send_msg,"AAAA");
MPI_Ssend(send_msg,5,MPI_CHAR,0,0,MPI_COMM_WORLD);
MPI_Recv(ack_msg,5,MPI_CHAR,0,100,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
}
void *master_server(void *null_arg)
{
char msg[5];
pthread_t tid;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
while(1)
{
MPI_Recv(msg,5,MPI_CHAR,1,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
pthread_create(&tid,&attr,master_server_handler,NULL);
// sleep(2);
// master_server_handler(NULL);
// pthread_create(&tid,NULL,master_server_handler,fun_arg);
// pthread_join(tid,NULL);
}
}
void *master_server_handler(void *arg)
{
static int count;
char ack[5];
count ++;
printf("recved a msg %d\n",count);
strcpy(ack,"ACK:");
MPI_Ssend(ack,5,MPI_CHAR,1,100,MPI_COMM_WORLD);
// MPI_Send(ack,5,MPI_CHAR,1,100,MPI_COMM_WORLD);
}
out put of the program:
recved a msg 1
recved a msg 2
recved a msg 3
recved a msg 4
recved a msg 5
recved a msg 6
recved a msg 7
recved a msg 8
recved a msg 9
recved a msg 10
recved a msg 11
recved a msg 12
recved a msg 13
recved a msg 14
recved a msg 15
back-trace of master when stuck:
(gdb) bt
#0 opal_progress () at runtime/opal_progress.c:175
#1 0x00002b17ed288f75 in opal_condition_wait (addr=<value optimized out>,
count=<value optimized out>, datatype=<value optimized out>, src=1, tag=0,
comm=0x601520, status=0x0) at ../../../../opal/threads/condition.h:99
#2 ompi_request_wait_completion (addr=<value optimized out>,
count=<value optimized out>, datatype=<value optimized out>, src=1, tag=0,
comm=0x601520, status=0x0) at ../../../../ompi/request/request.h:377
#3 mca_pml_ob1_recv (addr=<value optimized out>, count=<value optimized out>,
datatype=<value optimized out>, src=1, tag=0, comm=0x601520, status=0x0)
at pml_ob1_irecv.c:105
#4 0x00002b17ed1ef049 in PMPI_Recv (buf=0x2b17f2495120, count=5,
type=0x601320, source=1, tag=0, comm=0x601520, status=0x0) at precv.c:78
#5 0x0000000000400d75 in master_server (null_arg=0x0) at main.c:73
#6 0x0000003b5a00683d in start_thread () from /lib64/libpthread.so.0
#7 0x0000003b594d526d in clone () from /lib64/libc.so.6
back-trace of slave when stuck:
(gdb) bt
#0 0x00002adff87ef975 in opal_atomic_cmpset_32 (btl=<value optimized out>, endpoint=<value optimized out>,
registration=0x0, convertor=0x124e46a8, order=0 '\000', reserve=32, size=0x2adffda74fe8, flags=3)
at ../../../../opal/include/opal/sys/amd64/atomic.h:85
#1 opal_atomic_lifo_pop (btl=<value optimized out>, endpoint=<value optimized out>, registration=0x0,
convertor=0x124e46a8, order=0 '\000', reserve=32, size=0x2adffda74fe8, flags=3)
at ../../../../opal/class/opal_atomic_lifo.h:100
#2 mca_btl_sm_prepare_src (btl=<value optimized out>, endpoint=<value optimized out>, registration=0x0,
convertor=0x124e46a8, order=0 '\000', reserve=32, size=0x2adffda74fe8, flags=3) at btl_sm.c:697
#3 0x00002adff8877678 in mca_bml_base_prepare_src (sendreq=0x124e4600, bml_btl=0x124ea860, size=5, flags=0)
at ../../../../ompi/mca/bml/bml.h:339
#4 mca_pml_ob1_send_request_start_rndv (sendreq=0x124e4600, bml_btl=0x124ea860, size=5, flags=0)
at pml_ob1_sendreq.c:815
#5 0x00002adff8869e82 in mca_pml_ob1_send_request_start (buf=0x2adffda75100, count=5,
datatype=<value optimized out>, dst=0, tag=0, sendmode=MCA_PML_BASE_SEND_SYNCHRONOUS, comm=0x601520)
at pml_ob1_sendreq.h:363
#6 mca_pml_ob1_send (buf=0x2adffda75100, count=5, datatype=<value optimized out>, dst=0, tag=0,
sendmode=MCA_PML_BASE_SEND_SYNCHRONOUS, comm=0x601520) at pml_ob1_isend.c:119
#7 0x00002adff87d2be6 in PMPI_Ssend (buf=0x2adffda75100, count=5, type=0x601320, dest=0, tag=0,
comm=0x601520) at pssend.c:76
#8 0x0000000000400cf4 in send_heart_beat () at main.c:55
#9 0x0000000000400cb6 in heart_beat_daemon (null_arg=0x0) at main.c:44
#10 0x0000003b5a00683d in start_thread () from /lib64/libpthread.so.0
#11 0x0000003b594d526d in clone () from /lib64/libc.so.6
MPI provides four different levels of thread support: MPI_THREAD_SINGLE, MPI_THREAD_SERIALIZED, MPI_THREAD_FUNNELED, and MPI_THREAD_MULTIPLE. In order to be able to make MPI calls from different threads concurrently, you have to initialise MPI with the MPI_THREAD_MULTIPLE level of thread support and make sure that the library actually provides that level:
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
if (provided < MPI_THREAD_MULTIPLE)
{
printf("Error: the MPI library doesn't provide the required thread level\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
If you call MPI_Init instead of MPI_Init_thread, the library is free to chose whatever default thread support level its creators deemed best. For Open MPI that is MPI_THREAD_SINGLE, i.e. no support for threads. You can control the default level by setting the environment variable OMPI_MPI_THREAD_LEVEL but that is not recommended - MPI_Init_thread should be used instead.
IIRC, It's bad juju to call MPI_Init in one thread, then call MPI functions from another thread. Take a look at the documentation for MPI_Init_thread for how to make MPI thread-safe(-er).