Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1k8WQ2-0007Cd-94 for pljava-dev@arkaria.postgresql.org; Wed, 19 Aug 2020 22:18:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1k8WQ1-0005D4-8K for pljava-dev@arkaria.postgresql.org; Wed, 19 Aug 2020 22:18:53 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1k8WN2-0003gl-Vd for pljava-dev@lists.postgresql.org; Wed, 19 Aug 2020 22:15:49 +0000 Received: from anastigmatix.net ([68.171.219.55]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1k8WN0-0005ST-9j for pljava-dev@lists.postgresql.org; Wed, 19 Aug 2020 22:15:48 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=anastigmatix.net; s=default; h=Content-Transfer-Encoding:Content-Type: In-Reply-To:MIME-Version:Date:Message-ID:From:Cc:References:To:Subject:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=TZakYs4xS1el2OWpMWseJ3/UdojKFj9TOj2M7zjWFkw=; b=W2jSXnhVVRzGwSlQS/4WPEjpck upP/mzIj4HDfAXVGrg919wOORFcy8dVzFGEK9udMQFr5n3R2JhPj0R/GoJXGKSJvrXAhMzMRunEAM uJvwkQ2v7sxIaPzAnYeM4Txmw4ILX9YI7kuuRfZvwXNlO84rWRC0D+Rzv6Ddn5c7yzB7VggYU4X6q JdeCvx66hYr0T49uYAzAj8qnhCN5agMolort6CkCUADbHfn7TTlu8KoFl8ZaHea47RXZfNPYXNGM7 3I8T0DBXJgAovfHrQUs9HhQ6P0VjkmdjmGjoe5EcedGvEBytsioDpeKzaf1sVkNbI+SkUw11WrXR0 u1ipWMVw==; Received: from [184.19.31.139] (port=42324) by bay.acenet.us with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.93) (envelope-from ) id 1k8WMx-00FEJu-G9; Wed, 19 Aug 2020 18:15:44 -0400 Subject: Re: the ScriptingMojo To: Kartik Ohri References: <5F2EB313.8090706@anastigmatix.net> <5F2EC4F4.3080608@anastigmatix.net> <5F31EFEC.1080609@anastigmatix.net> <5F368380.9070203@anastigmatix.net> <5F368A99.6070709@anastigmatix.net> <5F36965C.60707@anastigmatix.net> <5F3A7DC6.8090905@anastigmatix.net> <5F3D32E9.80504@anastigmatix.net> <5F3D36BE.70703@anastigmatix.net> <5F3D38F8.7050907@anastigmatix.net> <5F3D3A75.5010304@anastigmatix.net> <5F3D3D2E.4070109@anastigmatix.net> <5F3D43BD.4020900@anastigmatix.net> Cc: pljava-dev@lists.postgresql.org From: Chapman Flack X-Enigmail-Draft-Status: N1110 Message-ID: <5F3DA48D.7090408@anastigmatix.net> Date: Wed, 19 Aug 2020 18:15:41 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.0 MIME-Version: 1.0 In-Reply-To: <5F3D43BD.4020900@anastigmatix.net> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-OutGoing-Spam-Status: No, score=-95.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - bay.acenet.us X-AntiAbuse: Original Domain - lists.postgresql.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - anastigmatix.net X-Get-Message-Sender-Via: bay.acenet.us: authenticated_id: chap@anastigmatix.net X-Authenticated-Sender: bay.acenet.us: chap@anastigmatix.net X-Source: X-Source-Args: X-Source-Dir: X-From-Rewrite: unmodified, already matched List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Hi Kartik, Taking an early look: - I think the runCommand method has kind of a misleading name for what it does, as it only gives you a ProcessBuilder for you to set up for running your command. Maybe it would be better to just call that one ... processBuilder? - All the same, I think a runCommand method would also be good to have; that would be what you call after getting your ProcessBuilder from processBuilder and configuring it for the command you want. That method would take care of ProcessBuilder.start() and waiting for completion and checking the exit status. I think there would be few times the script code would want to do those things separately (and if it ever did, it could anyway; no one is forcing it to use runCommand). Later on, it will be even better to have runCommand, as we will eventually want not to set the process stdout and stderr to INHERIT, but to have them as pipes and read them. At that point, runCommand should have an additional parameter, some JavaScript lambda that will be called back with messages read from the process, and will classify the messages as error/warning/info and pass them to the right Maven log method. That should be done in script because the patterns used to classify the messages will almost certainly need to be tailored for each compiler/linker. That will be a little tricky, because runCommand will need to use more than one thread, to be able to read both streams from the process and wait for the process to exit. But the script engine does not want to be shared between threads. So runCommand might create a concurrent queue, start threads that will read the process output and place messages on the queue, while runCommand just reads from the queue and passes messages to the script callback, until the process is done. But that can be later; just letting stdout and stderr be INHERIT is fine for now. - Once there is processBuilder and runCommand, processBuilder can set a default for the working directory before it returns the ProcessBuilder, but I would move the existence test and directory creation into runCommand; no need to do the work up front when the caller might change the directory setting. - I was thinking of simplifying the parameters to processBuilder, to not need the caller to separately pass the command string and a list of the rest of the arguments. An idea that just hit me was why not just processBuilder(Consumer>)? A script could use it like: var pb = processBuilder(function(l) { l.add(command); l.addAll(stuff); l.add(thing); ... }); so the script would avoid the messiness of allocating its own ArrayList and so on. On the Java side that's just pb = new ProcessBuilder(); callback.accept(pb.command()); ... return pb; Once there is a platform/OS 'dispatcher object' structure, I think the common methods compile(...), link(...), and so on, need their parameter lists carefully thought out. One parameter to compile(), for example, should just be a list of includes, without the -I; the method needs to know the right syntax for its compiler. Another parameter should be a simple map of defines; again the method needs to know if -Dname=value is right for its compiler. Similar considerations for link(). It might be worthwhile to define an abstract class in Java that has the necessary methods; it could also supply some other useful methods or default implementations. I think the javascript could then do something like: var platforms = { 'Linux': { compile: function(...) { ... }, link: function... }, 'Windows' : { ... }, ... } var impl = new AbstractPGXS(platforms['Linux']); which would enforce that the needed methods were all present, and the ones supplied in Java would be naturally available too. I have not tried this out to make sure it does what I expect in both nashorn and graal. Regards, -Chap