unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Improving the speed of guix time-machine for development environments
@ 2024-03-28  3:52 Richard Sent
  0 siblings, 0 replies; 8+ messages in thread
From: Richard Sent @ 2024-03-28  3:52 UTC (permalink / raw)
  To: guix-devel

Hi Guix,

To my knowledge what I'm asking for can't currently be done, but if it
can feel free to disregard.

I think channels listed in channels.scm files should optionally support
using whatever channel version is already in the user's profile, if
present. This would significantly speed up entering development
environments composed of Guix channels. Consider the following
situation:

1. Repository A contains some code, an unmerged Guix package, and a
.guix-channel file.

2. Repository B declares an unmerged Guix package that depends on A's
package

3. Repository B doesn't want to duplicate the package definition in A,
so it adds a channel dependency in B's .guix-channel

4. Repository B wants to make it easy to enter a development environment
that includes repository A's channel, so it tracks a channels.scm file
with the following content:

--8<---------------cut here---------------start------------->8---
(append (list (channel
               (name 'B)
               (url (string-append "file://" (getcwd)))))
        %default-channels)
--8<---------------cut here---------------end--------------->8---

Now in order to build B, I need to enter a Guix development environment
that includes A's channel. The only option I know for that is
time-machine, e.g. "guix time-machine -C channels.scm -- build -f
guix.scm".

Unfortunately, *I may be delayed every time I enter the development
environment by several minutes while Guix computes a new derivation due
to an update in %default-channels*.

time-machine will update ALL channels in channels.scm to the master
branch (by default) every time I try to enter a development environment
(e.g. "guix time-machine -C channels.scm -- shell -CDf guix.scm").

I don't think pinning Guix to a specific commit in channels.scm is the
right solution.

1. That increases the maintenance burden (If A updates to use newer Guix
code, now all dependents of A need to be manually updated to use newer
Guix commits).

2. It makes it easy to mask breakages for an extended period.

3. It implies that B doesn't work on newer versions.

4. Any developer working on the repo will pull an unneeded copy of the channel.

I think this is a side effect of time-machine serving dual purposes.
One is providing a reproducible environment for result replication, the
other is providing a development environment for collections of channels.

My proposed solution is to add a (prefer-local?) field to (channel ...).
When set, time-machine would first see if there is a channel with the
same name in the user's profile. If so, it will include that channel in
the time-machine environment instead of fetching it. If not, it behaves
as normal and fetches the channel from url.

As a workaround, it *may* be possible to achieve this via a command like
~guix time-machine -C channels.scm --commit $(guix describe |
<some_crazy_awk_or_grep_chain)~, but I don't feel that this is a valid
solution. From what I understand --commit only works on the 'guix
channel, but I suspect this proposal could prove useful for other major
channels as well. It's also very inelegant :)

As a side effect, `guix pull -C` would support only upgrading certain
channels while "soft-pinning" others. Maybe that's good?

-- 
Take it easy,
Richard Sent
Making my computer weirder one commit at a time.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Improving the speed of guix time-machine for development environments
@ 2024-05-27  2:00 Richard Sent
  2024-05-31  9:58 ` jbranso
  2024-06-01 13:18 ` Ludovic Courtès
  0 siblings, 2 replies; 8+ messages in thread
From: Richard Sent @ 2024-05-27  2:00 UTC (permalink / raw)
  To: guix-devel; +Cc: richard

Hi Guix!

> I think channels listed in channels.scm files should optionally support
> using whatever channel version is already in the user's profile, if
> present. This would significantly speed up entering development
> environments composed of Guix channels.

> Unfortunately, *I may be delayed every time I enter the development
> environment by several minutes while Guix computes a new derivation
> due to an update in %default-channels*.

I wound up implementing a proof of concept for this idea here:

https://www.freakingpenguin.com/blog/guix-tricks-self-referential-channelsscm-files.html

--8<---------------cut here---------------start------------->8---
(define (soft-pin-channel input-channel)
  "Given @var{channel}, return a new version of channel that uses the
current profile's commit of said channel. If the channel is not present,
commit is #f."
  (define (desired-channel? channel)
    (equal? (channel-name input-channel)
            (channel-name channel)))

  (define (profile-commit input-channel)
    (call/ec
     (lambda (return)
       (map (lambda (x)
              (when (desired-channel? x)
                (return (channel-commit x))))
            (current-channels))
       #f)))

  (channel
   (inherit input-channel)
   (commit (profile-commit input-channel))))
--8<---------------cut here---------------end--------------->8---

If people think this is useful, I'm happy to flesh out the idea more and
submit a proper patch. In my experience this does improve the
development experience when setting up developer tools that rely on
custom channels. At least when there's a new Guix commit, I don't have
to wait several minutes for a new Guix channel collection to build, but
without pinning it to a specific commit.

At present I can think of soft-pinning a list of channels by name being
useful. I can also see an option to only fetch dependencies of a
channel, not the channel itself, being useful. I would definitely
appreciate feedback or use cases! :)

-- 
Take it easy,
Richard Sent
Making my computer weirder one commit at a time.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Improving the speed of guix time-machine for development environments
  2024-05-27  2:00 Richard Sent
@ 2024-05-31  9:58 ` jbranso
  2024-06-01 13:18 ` Ludovic Courtès
  1 sibling, 0 replies; 8+ messages in thread
From: jbranso @ 2024-05-31  9:58 UTC (permalink / raw)
  To: Richard Sent, guix-devel; +Cc: richard

May 26, 2024 at 10:00 PM, "Richard Sent" <richard@freakingpenguin.com> wrote:



> 
> Hi Guix!
> 
> > 
> > I think channels listed in channels.scm files should optionally support
> > 
> >  using whatever channel version is already in the user's profile, if
> > 
> >  present. This would significantly speed up entering development
> > 
> >  environments composed of Guix channels.
> > 
> >  Unfortunately, *I may be delayed every time I enter the development
> > 
> >  environment by several minutes while Guix computes a new derivation
> > 
> >  due to an update in %default-channels*.
> > 
> 
> I wound up implementing a proof of concept for this idea here:
> 
> https://www.freakingpenguin.com/blog/guix-tricks-self-referential-channelsscm-files.html
> 
> --8<---------------cut here---------------start------------->8---
> 
> (define (soft-pin-channel input-channel)
> 
>  "Given @var{channel}, return a new version of channel that uses the
> 
> current profile's commit of said channel. If the channel is not present,
> 
> commit is #f."
> 
>  (define (desired-channel? channel)
> 
>  (equal? (channel-name input-channel)
> 
>  (channel-name channel)))
> 
>  (define (profile-commit input-channel)
> 
>  (call/ec
> 
>  (lambda (return)
> 
>  (map (lambda (x)
> 
>  (when (desired-channel? x)
> 
>  (return (channel-commit x))))
> 
>  (current-channels))
> 
>  #f)))
> 
>  (channel
> 
>  (inherit input-channel)
> 
>  (commit (profile-commit input-channel))))
> 
> --8<---------------cut here---------------end--------------->8---
> 
> If people think this is useful, I'm happy to flesh out the idea more and
> 
> submit a proper patch. In my experience this does improve the
> 
> development experience when setting up developer tools that rely on
> 
> custom channels. At least when there's a new Guix commit, I don't have
> 
> to wait several minutes for a new Guix channel collection to build, but
> 
> without pinning it to a specific commit.
> 
> At present I can think of soft-pinning a list of channels by name being
> 
> useful. I can also see an option to only fetch dependencies of a
> 
> channel, not the channel itself, being useful. I would definitely
> 
> appreciate feedback or use cases! :)

Sounds worthwhile.  I would submit the patch as-is, so it is not lost.

:)

> 
> -- 
> 
> Take it easy,
> 
> Richard Sent
> 
> Making my computer weirder one commit at a time.
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Improving the speed of guix time-machine for development environments
  2024-05-27  2:00 Richard Sent
  2024-05-31  9:58 ` jbranso
@ 2024-06-01 13:18 ` Ludovic Courtès
  2024-06-01 14:40   ` Richard Sent
  1 sibling, 1 reply; 8+ messages in thread
From: Ludovic Courtès @ 2024-06-01 13:18 UTC (permalink / raw)
  To: Richard Sent; +Cc: guix-devel

Hi Richard,

Richard Sent <richard@freakingpenguin.com> skribis:

>> I think channels listed in channels.scm files should optionally support
>> using whatever channel version is already in the user's profile, if
>> present. This would significantly speed up entering development
>> environments composed of Guix channels.
>
>> Unfortunately, *I may be delayed every time I enter the development
>> environment by several minutes while Guix computes a new derivation
>> due to an update in %default-channels*.

I understand and share the frustration regarding performance.

To address the problem, I would suggest a different route (the problem
with the patch you propose here is that it makes things unpredicatable
and stateful: you’d end up using whatever commit happens to be already
in a profile).

My suggestion would be for ‘guix pull’ to populate the same cache that
‘guix time-machine’ uses.  That way, if you time-travel to a commit you
already have in a profile, it would be instantaneous.

I started looking into it a while back and there were some
complications, but I forgot the details.

WDYT?  Would this be an improvement for you?

Thanks,
Ludo’.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Improving the speed of guix time-machine for development environments
  2024-06-01 13:18 ` Ludovic Courtès
@ 2024-06-01 14:40   ` Richard Sent
  2024-06-02 20:53     ` Ludovic Courtès
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Sent @ 2024-06-01 14:40 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel, jbranso

Hi Ludo!

Ludovic Courtès <ludo@gnu.org> writes:

> I understand and share the frustration regarding performance.
>
> To address the problem, I would suggest a different route (the problem
> with the patch you propose here is that it makes things unpredicatable
> and stateful: you’d end up using whatever commit happens to be already
> in a profile).
>
> My suggestion would be for ‘guix pull’ to populate the same cache that
> ‘guix time-machine’ uses.  That way, if you time-travel to a commit you
> already have in a profile, it would be instantaneous.
>
> I started looking into it a while back and there were some
> complications, but I forgot the details.
>
> WDYT?  Would this be an improvement for you?

Thanks for the suggestion! If I understand correctly, I don't believe it
would solve my problems with time-machine though for development
environments.

If I want to use time-machine as part of entering a development
environment for some channel collection and a new guix commit is pushed,
then the next time I invoke that same time-machine command there will be
a large delay as Guix fetches, authenticates, computes, and builds an
entirely new derivation. With your proposal, I'd only avoid that problem
if I coincidentally happened to run guix pull in-between.

I don't believe hard-pinning the guix channel is an appropriate solution
in this case since it has several drawbacks as discussed in [1].

I don't envision this as something to be used in all cases (like
reproducible research). I think it serves as a "yes, this project
requires channel X, but the odds of breakage due to an update are very
low and we are willing to make that tradeoff in order to enter our
development tools faster".

Obviously if breakage is detected in the development environment
developers can choose to go back and hard-pin as required. But if we
hard-pinned from the beginning we wouldn't detect that breakage as
quickly. And if we didn't pin at all we'd have no speedup.

Is it really any different state-wise than pinning a channel to a moving
target like a branch? Instead of being unpredictable and stateful in the
time domain, it's unpredictable and stateful in the user's "profile
domain", for lack of a better phrase.

Perhaps as a compromise we can support optionally passing some "minimum
commit" (or tag). This should reduce the fragility of soft-pinning as it
ensures some minimum version of the channel is present.

If that's not enough, a warning could be emitted so user's know that
soft-pinning is taking place and what commit is used. I'd prefer to
avoid this, but it is an option.

>> I think this is a side effect of time-machine serving dual purposes.
>> One is providing a reproducible environment for result replication,
>> the other is providing a development environment for collections of
>> channels.

[1]: https://lists.gnu.org/archive/html/guix-devel/2024-03/msg00265.html

-- 
Take it easy,
Richard Sent
Making my computer weirder one commit at a time.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Improving the speed of guix time-machine for development environments
  2024-06-01 14:40   ` Richard Sent
@ 2024-06-02 20:53     ` Ludovic Courtès
  2024-06-02 21:40       ` Richard Sent
  0 siblings, 1 reply; 8+ messages in thread
From: Ludovic Courtès @ 2024-06-02 20:53 UTC (permalink / raw)
  To: Richard Sent; +Cc: guix-devel, jbranso

Hi Richard,

Richard Sent <richard@freakingpenguin.com> skribis:

> If I want to use time-machine as part of entering a development
> environment for some channel collection and a new guix commit is pushed,
> then the next time I invoke that same time-machine command there will be
> a large delay as Guix fetches, authenticates, computes, and builds an
> entirely new derivation. With your proposal, I'd only avoid that problem
> if I coincidentally happened to run guix pull in-between.
>
> I don't believe hard-pinning the guix channel is an appropriate solution
> in this case since it has several drawbacks as discussed in [1].

I’m not sure I understand the use case.  Two different but “common” (?)
use cases come to mind.

First one is when you want to share the exact same environment within a
team of developers, say.  In that case, you have a ‘channels.scm’ that
pins commits.  The first ‘guix time-machine’ is expensive but subsequent
invocations are instantaneous (cached).  Occasionally, the team updates
‘channels.scm’ to point to a more recent commit of Guix and other
channels.

Second one is CI-style: you want to build a package against the latest
commit of each relevant channel, all the time.  In that case, you pay
the price on every ‘guix time-machine’ invocation.

You seem to be looking for something kinda “in between”, is that right?

Ludo’.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Improving the speed of guix time-machine for development environments
  2024-06-02 20:53     ` Ludovic Courtès
@ 2024-06-02 21:40       ` Richard Sent
  2024-06-06 15:11         ` Ludovic Courtès
  0 siblings, 1 reply; 8+ messages in thread
From: Richard Sent @ 2024-06-02 21:40 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guix-devel, jbranso

Hi Ludo,

Ludovic Courtès <ludo@gnu.org> writes:

> I’m not sure I understand the use case.  Two different but “common” (?)
> use cases come to mind.
>
> First one is when you want to share the exact same environment within a
> team of developers, say.  In that case, you have a ‘channels.scm’ that
> pins commits.  The first ‘guix time-machine’ is expensive but subsequent
> invocations are instantaneous (cached).  Occasionally, the team updates
> ‘channels.scm’ to point to a more recent commit of Guix and other
> channels.
>
> Second one is CI-style: you want to build a package against the latest
> commit of each relevant channel, all the time.  In that case, you pay
> the price on every ‘guix time-machine’ invocation.
>
> You seem to be looking for something kinda “in between”, is that
> right?

Yes, that "in-between" use case is what I'm going for. Hard-pinning
solves, for example, the "random 5 minute time-machine when invoking
Geiser" problem (minus the first use), but introduces others that aren't
universally desirable in a short-lived development environment. In other
words, it's overkill sometimes. :)

In a development environment, I want to achieve two things that are
diametrically opposed:

1. Responsiveness/Speed of entry

   1. Should be obvious why this is good ;)

2. Continual updates of channels unless explicitly pinned

   1. Detect breakages faster without needing a dedicated Cuirass CI
   server.

   2. Less maintainence burden to regularly update pinned commits,
   particularly as a channel dependency tree grows.

I feel that soft-pinning strikes a balance between those two goals that
is useful when dependencies on a frequently updated channel are unlikely
to break between commits.

Elaborating on 2.2, consider a dependency chain that looks like

--8<---------------cut here---------------start------------->8---
   _______
  /       \
 /         v 
Guix-->A-->B
--8<---------------cut here---------------end--------------->8---

If B hard-pins Guix to "foo" and A is updated to Guix "bar", B needs to
update their hard-pinned Guix commit in channels.scm to >= "bar" to have
a functional development environment again. Alternatively, B could
hard-pin A, but if A is a channel the developers of B control they
probably want to always use the latest version.

Now you're in a catch-22 situation of "Do we hard-pin Guix in B and
manually update it every time A's requirements change, or do we not pin
Guix at all and deal with regular 5 minute pauses during development?"

As channels become more popular and dependency trees grow, this'll
become even more annoying. If B is only importing a couple Guix modules
that are unlikely to incompatibly change, it's basically wasted effort.

This is outside the scope of this topic, but I think it could be
interesting if the dependency channels in .guix-channel could specify
minimum commits as well.

-- 
Take it easy,
Richard Sent
Making my computer weirder one commit at a time.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Improving the speed of guix time-machine for development environments
  2024-06-02 21:40       ` Richard Sent
@ 2024-06-06 15:11         ` Ludovic Courtès
  0 siblings, 0 replies; 8+ messages in thread
From: Ludovic Courtès @ 2024-06-06 15:11 UTC (permalink / raw)
  To: Richard Sent; +Cc: guix-devel, jbranso

Richard Sent <richard@freakingpenguin.com> skribis:

>    2. Less maintainence burden to regularly update pinned commits,
>    particularly as a channel dependency tree grows.
>
> I feel that soft-pinning strikes a balance between those two goals that
> is useful when dependencies on a frequently updated channel are unlikely
> to break between commits.
>
> Elaborating on 2.2, consider a dependency chain that looks like
>
>    _______
>   /       \
>  /         v 
> Guix-->A-->B
>
> If B hard-pins Guix to "foo" and A is updated to Guix "bar", B needs to
> update their hard-pinned Guix commit in channels.scm to >= "bar" to have
> a functional development environment again. Alternatively, B could
> hard-pin A, but if A is a channel the developers of B control they
> probably want to always use the latest version.
>
> Now you're in a catch-22 situation of "Do we hard-pin Guix in B and
> manually update it every time A's requirements change, or do we not pin
> Guix at all and deal with regular 5 minute pauses during development?"
>
> As channels become more popular and dependency trees grow, this'll
> become even more annoying. If B is only importing a couple Guix modules
> that are unlikely to incompatibly change, it's basically wasted effort.

I see.  I wonder if another mechanism I suggested could help:

  https://lists.gnu.org/archive/html/guix-devel/2024-01/msg00201.html

Especially if the channels.json is published by a CI system.

Thoughts?

Ludo’.


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-06-06 15:11 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-28  3:52 Improving the speed of guix time-machine for development environments Richard Sent
  -- strict thread matches above, loose matches on Subject: below --
2024-05-27  2:00 Richard Sent
2024-05-31  9:58 ` jbranso
2024-06-01 13:18 ` Ludovic Courtès
2024-06-01 14:40   ` Richard Sent
2024-06-02 20:53     ` Ludovic Courtès
2024-06-02 21:40       ` Richard Sent
2024-06-06 15:11         ` Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).