diff mbox series

[bug#52555,RFC,v2,3/5] Add (guix eris).

Message ID 20220125192201.7582-4-pukkamustard@posteo.net
State New
Headers show
Series Decentralized substitute distribution with ERIS | expand

Checks

Context Check Description
cbaines/comparison success View comparision
cbaines/git branch success View Git branch
cbaines/applying patch success View Laminar job
cbaines/issue success View issue

Commit Message

pukkamustard Jan. 25, 2022, 7:21 p.m. UTC
* guix/ipfs.scm: New file.
* Makefile.am (MODULES): Add it.
---
 Makefile.am   |  1 +
 guix/eris.scm | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100644 guix/eris.scm

Comments

M Jan. 29, 2022, 9:23 p.m. UTC | #1
pukkamustard schreef op di 25-01-2022 om 19:21 [+0000]:
> +(define (ipfs-daemon-alive?)
> +  "Attempt to connect to the IPFS daemon. Returns #t if the daemon is alive
> +and #f else."
> +  (with-exception-handler
> +      (const #f)
> +    (lambda _
> +      (let ((response _
> +                      (http-post (string-append (%ipfs-base-url)
> +                                                "/api/v0/version"))))
> +        (equal? 200 (response-code response))))
> +    #:unwind? #t))

This should preferably only be catching exceptions indicating that
the daemon is down (exceptions indicating 404s, or system-errors
indicating network errors, ...).

> +
> +(define guix-eris-block-reducer
> +  (case-lambda
> +
> +    ;; Check if IPFS Daemon is running.
> +    (() (if (ipfs-daemon-alive?)
> +            (eris-blocks-ipfs-reducer)
> +            #f))
> +
> +    ;; Completion. Nothing to do.
> +    ((_) #t)
> +
> +    ((ipfs ref-block)
> +     ;; If IPFS has been initialized store block there
> +     (if ipfs
> +         (eris-blocks-ipfs-reducer ipfs ref-block)
> +         ipfs))))

This (ipfs-daemon-alive?) seems racy, although it's probably not.
Can we do

(define guix-eris-block-reducer
  (case-lambda
    (() (guard (c (oops-it-fails-because-the-daemon-cannot-be-
contacted? c)
                  #false)
          (eris-block-ipfs-reducer))
    [...]))

instead? (I don't think this will work as-is, because from the name and
thunkiness, it would appear that eris-block-ipfs-reducer returns a
procedure ...

Greetings,
Maxime.
M Jan. 29, 2022, 9:24 p.m. UTC | #2
pukkamustard schreef op di 25-01-2022 om 19:21 [+0000]:
> +  #:use-module (eris)
> +  #:use-module (eris blocks ipfs)

guile-eris is an optional dependency, so this needs to be autoloaded.
Or guix/eris.scm must only be compiled when guile-eris is available.

Greetings,
Maxime.
pukkamustard Feb. 2, 2022, 10:28 a.m. UTC | #3
Maxime Devos <maximedevos@telenet.be> writes:

> pukkamustard schreef op di 25-01-2022 om 19:21 [+0000]:
>> +(define (ipfs-daemon-alive?)
>> +  "Attempt to connect to the IPFS daemon. Returns #t if the daemon is alive
>> +and #f else."
>> +  (with-exception-handler
>> +      (const #f)
>> +    (lambda _
>> +      (let ((response _
>> +                      (http-post (string-append (%ipfs-base-url)
>> +                                                "/api/v0/version"))))
>> +        (equal? 200 (response-code response))))
>> +    #:unwind? #t))
>
> This should preferably only be catching exceptions indicating that
> the daemon is down (exceptions indicating 404s, or system-errors
> indicating network errors, ...).

Yes, I guess it could be checked a bit finer. But at the end if an
exception happens then the IPFS daemon is probably not reachable, right?
If we don't care about the reason why it is not reachable then why
bother with catching finer grained exceptions?

>> +
>> +(define guix-eris-block-reducer
>> +  (case-lambda
>> +
>> +    ;; Check if IPFS Daemon is running.
>> +    (() (if (ipfs-daemon-alive?)
>> +            (eris-blocks-ipfs-reducer)
>> +            #f))
>> +
>> +    ;; Completion. Nothing to do.
>> +    ((_) #t)
>> +
>> +    ((ipfs ref-block)
>> +     ;; If IPFS has been initialized store block there
>> +     (if ipfs
>> +         (eris-blocks-ipfs-reducer ipfs ref-block)
>> +         ipfs))))
>
> This (ipfs-daemon-alive?) seems racy, although it's probably not.
> Can we do
>
> (define guix-eris-block-reducer
>   (case-lambda
>     (() (guard (c (oops-it-fails-because-the-daemon-cannot-be-
> contacted? c)
>                   #false)
>           (eris-block-ipfs-reducer))
>     [...]))
>
> instead? (I don't think this will work as-is, because from the name and
> thunkiness, it would appear that eris-block-ipfs-reducer returns a
> procedure ...

Yes, eris-block-ipfs-reducer returns and SRFI-171 reducer. This is a
3-arity procedure that is either initialized, called with a block to
reduce and finalized.

The #f that the initialization case returns (0-arity call) is the state
of the reducer. In the block reducing case (2-ary call) the state (the
ipfs variable) is checked if ipfs is alive. If not the blocks are just
forgotten.

So guix-eris-block-reducer always returns a SRF-171 reducer, regardless
of if IPFS is alive or not. This is important as the ERIS URN can still
be computed without the IPFS daemon running.

-pukkamustard
M Feb. 2, 2022, 3:36 p.m. UTC | #4
pukkamustard schreef op wo 02-02-2022 om 10:28 [+0000]:
> > pukkamustard schreef op di 25-01-2022 om 19:21 [+0000]:
> > > +(define (ipfs-daemon-alive?)
> > > +  "Attempt to connect to the IPFS daemon. Returns #t if the
> > > daemon is alive
> > > +and #f else."
> > > +  (with-exception-handler
> > > +      (const #f)
> > > +    (lambda _
> > > +      (let ((response _
> > > +                      (http-post (string-append (%ipfs-base-url)
> > > +                                               
> > > "/api/v0/version"))))
> > > +        (equal? 200 (response-code response))))
> > > +    #:unwind? #t))
> > 
> > This should preferably only be catching exceptions indicating that
> > the daemon is down (exceptions indicating 404s, or system-errors
> > indicating network errors, ...).
> 
> Yes, I guess it could be checked a bit finer. But at the end if an
> exception happens then the IPFS daemon is probably not reachable,
> right?
> If we don't care about the reason why it is not reachable then why
> bother with catching finer grained exceptions?

The exception could be caused by, say:

  * an unbound variable
  * wrong arity
  * type error
  * stack overflow
  * prompt tag does not exist in current environment
  * out of memory

Except for the last one, these causes are all bugs and hence shouldn't
be surpressed.  Granted, this is a bit unlikely since this use of
'http-post' is very simple, but it's far from impossible for
(web client) to have a bug.

Greetings,
Maxime.
diff mbox series

Patch

diff --git a/Makefile.am b/Makefile.am
index a10aeb817b..7219386361 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -131,6 +131,7 @@  MODULES =					\
   guix/cve.scm					\
   guix/workers.scm				\
   guix/ipfs.scm					\
+  guix/eris.scm					\
   guix/build-system.scm				\
   guix/build-system/android-ndk.scm		\
   guix/build-system/ant.scm			\
diff --git a/guix/eris.scm b/guix/eris.scm
new file mode 100644
index 0000000000..163bbe05ac
--- /dev/null
+++ b/guix/eris.scm
@@ -0,0 +1,55 @@ 
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2022 pukkamustard <pukkamustard@posteo.net>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix eris)
+  #:use-module (eris)
+  #:use-module (eris blocks ipfs)
+  #:use-module (web client)
+  #:use-module (web response)
+  #:use-module (srfi srfi-71)
+
+  #:export (guix-eris-block-reducer))
+
+(define (ipfs-daemon-alive?)
+  "Attempt to connect to the IPFS daemon. Returns #t if the daemon is alive
+and #f else."
+  (with-exception-handler
+      (const #f)
+    (lambda _
+      (let ((response _
+                      (http-post (string-append (%ipfs-base-url)
+                                                "/api/v0/version"))))
+        (equal? 200 (response-code response))))
+    #:unwind? #t))
+
+(define guix-eris-block-reducer
+  (case-lambda
+
+    ;; Check if IPFS Daemon is running.
+    (() (if (ipfs-daemon-alive?)
+            (eris-blocks-ipfs-reducer)
+            #f))
+
+    ;; Completion. Nothing to do.
+    ((_) #t)
+
+    ((ipfs ref-block)
+     ;; If IPFS has been initialized store block there
+     (if ipfs
+         (eris-blocks-ipfs-reducer ipfs ref-block)
+         ipfs))))