whitfin / cachex

A powerful caching library for Elixir with support for transactions, fallbacks and expirations
https://hexdocs.pm/cachex/
MIT License
1.6k stars 103 forks source link

[Elixir 1.15] ** (MatchError) no match of right hand side value: {1, {:error, :no_cache}} #318

Closed kianmeng closed 10 months ago

kianmeng commented 12 months ago

Env:

$ asdf current
elixir          1.15.7-otp-26   /home/foobar/.tool-versions
erlang          26.1.2          /home/foobar/.tool-versions

Steps to reproduce:

cd /tmp
git clone https://github.com/whitfin/cachex
cd cachex
mix deps.update
epmd -daemon
mix test --trace
warning: TestHelper.delete_on_exit/1 is undefined (module TestHelper is not available or is yet to be defined)                            
  test/lib/cachex_case/helper.ex:96: CachexCase.Helper.delete_on_exit/1                                                                   

warning: TestHelper.on_exit/2 is undefined (module TestHelper is not available or is yet to be defined)                                   
  test/lib/cachex_case/helper.ex:49: CachexCase.Helper.create_cache_cluster/2                                                             

warning: Cachex.set/3 is deprecated. Please migrate to using put/4 instead.                                                               
Invalid call found at 3 locations:                                                                                                        
  test/cachex/actions/set_test.exs:12: Cachex.Actions.SetTest."test forwarding calls to put(3/4)"/1                                       
  test/cachex/actions/set_test.exs:43: Cachex.Actions.SetTest."test forwarding calls to put(3/4) in a cache cluster"/1                    
  test/cachex/actions/set_test.exs:44: Cachex.Actions.SetTest."test forwarding calls to put(3/4) in a cache cluster"/1                    

warning: Cachex.set/4 is deprecated. Please migrate to using put/4 instead.                                                               
  test/cachex/actions/set_test.exs:13: Cachex.Actions.SetTest."test forwarding calls to put(3/4)"/1                                       

warning: Cachex.set_many/2 is deprecated. Please migrate to using put_many/3 instead.
Invalid call found at 3 locations: 
  test/cachex/actions/set_many_test.exs:12: Cachex.Actions.SetManyTest."test forwarding calls to put_many(2/3)"/1
  test/cachex/actions/set_many_test.exs:49: Cachex.Actions.SetManyTest."test adding new entries to a cache cluster"/1
  test/cachex/actions/set_many_test.exs:68: Cachex.Actions.SetManyTest."test multiple slots will return a :cross_slot error"/1

warning: Cachex.set_many/3 is deprecated. Please migrate to using put_many/3 instead.
  test/cachex/actions/set_many_test.exs:13: Cachex.Actions.SetManyTest."test forwarding calls to put_many(2/3)"/1

...

Cachex.Actions.StatsTest [test/cachex/actions/stats_test.exs]
  * test retrieving stats from a diabled cache [L#36]
  * test retrieving stats from a diabled cache (1.2ms) [L#36]
  * test retrieving stats for a cache [L#7]
  * test retrieving stats for a cache (1.5ms) [L#7]
  * test retrieving different rate combinations [L#50]
  * test retrieving different rate combinations (6.4ms) [L#50]
  * test retrieving stats for a cache cluster [L#153]
13:37:39.145 [error] GenServer :lsytwcvn_janitor terminating
** (MatchError) no match of right hand side value: {2, {:error, :no_cache}}
    (cachex 3.6.0) lib/cachex/services/janitor.ex:110: Cachex.Services.Janitor.handle_info/2
    (stdlib 5.1.1) gen_server.erl:1077: :gen_server.try_handle_info/3
    (stdlib 5.1.1) gen_server.erl:1165: :gen_server.handle_msg/6
    (stdlib 5.1.1) proc_lib.erl:241: :proc_lib.init_p_do_apply/3
Last message: :ttl_check
State: {{:cache, :lsytwcvn, %{}, false, {:expiration, nil, 3000, true}, {:fallback, nil, nil}, {:hooks, [], []}, {:limit, nil, Cachex.Policy.LRW, 0.1, []}, [:"lsytwcvn1@127.0.0.1", :"manager@127.0.0.1"], false, []}, %{}}

...
whitfin commented 11 months ago

I managed to reproduce this, have a feeling it's related to OTP more than the Elixir version (unless it's somehow a bug in Elixir, because they shouldn't have broken the interface in a minor release).

I'll investigate further!

whitfin commented 10 months ago

Okay, I'm fairly confident this is only showing up during tests, I don't think there's a "real" bug here.

It seems to be that the Janitor is not being closed properly when ExUnit exits; it's some sort of cleanup issue in tests that somehow only became a thing in Elixir v1.15+.

whitfin commented 10 months ago

Ah, never mind - I found the issue and filed https://github.com/whitfin/cachex/pull/321.

I guess older versions of Elixir were just masking this issue, but it's a legitimate bug (in the tests). I've fixed it and this shouldn't happen anymore.