Files
lespiedsdanslecode/content/2009/2009-06-09-ruby-file-open-w-acces-concurrent.md
T
2020-03-27 22:43:43 +01:00

3.6 KiB
Raw Blame History

layout, title
layout title
post Ruby File.open 'w' Acces concurrent

Je viens de tomber sur quelque chose d’étrange dans lutilisation de lobjet IO de Ruby : La gestion des verrous sur les fichiers. Alors jai surement du rater quelque chose, mais voici mon histoire...

  {% highlight ruby %}
  require 'test/unit'

  DUCK="duck"
  ELEPHANT="elephant"
  SNAKE="snake"
  FILE="test_file"

  class TestFileConcurrencyAccess < Test::Unit::TestCase
    def test_concurrency_access
      t1 = Thread.start do
        File.open(FILE, "w") do |file|
          file.puts SNAKE
          file.flush
          sleep 8
          file.puts DUCK
        end
      end
      File.open(FILE,"r") do |f1|
        assert SNAKE, f1.read
      end
      t2 = Thread.start do
        File.open(FILE,"w") do |f|
          sleep 2
          f.puts ELEPHANT
        end
      end
      t2.join
      File.open(FILE,"r") do |f2|
        assert ELEPHANT, f2.read
      end

      t1.join
      File.open(FILE,"r") do |f3|
        assert SNAKE, f3.readline
        assert DUCK, f3.readline
      end

    end
  end
  {% endhighlight %}

fichier source

Le resultat dexecution de ce test donne une erreur sur la dernière lecture:

  {% highlight bash %}
  Loaded suite test_file_concurrency_access

  Started
  E

  Finished in 8.003509 seconds.
  1) Error:
  test_concurrency_access(TestFileConcurrencyAccess):
  EOFError: end of file reached
      test_file_concurrency_access.rb:38:in `readline
      test_file_concurrency_access.rb:38:in `test_concurrency_access
      test_file_concurrency_access.rb:36:in `open
      test_file_concurrency_access.rb:36:in `test_concurrency_access

  1 tests, 3 assertions, 0 failures, 1 errors
  {% endhighlight %}

Mais ce qui me gène (et qui ne ressort pas dans mon test, je lavoue) cest que jaurais pensé que le deuxième File.open ne puisse pas sexecuté, et me renvoie une Error du type: “Le fichier est déjà ouvert en écriture par quelquun dautres”... Mais non, et du coup, jai un fichier assez moche qui ne ressemble à rien:

elephduck

Alors quon pourrait penser obtenir un truc dans le genre:

snake
duck

Avec éventuellement une erreur sur l’écriture d’éléphant dans le fichier.

Jai également fait un essai en utilisant le code contenu dans chaque thread pour les executer dans deux console différentes, jarrive au même résultat (cest du coup dans test/unit, mais au niveau du contenu de FILE à la fin, jai là même chose...) Fichier write_quickly.rb pour l’écriture dELEPHANT Fichier write_slowly.rb pour l’écriture de SNAKE et DUCK

Bref, je suis perplexe. Javoue ne pas avoir envie denvoyer cela sur la mailing-liste Ruby-talk, ni sur celle de JRuby dailleurs (car jai vérifier, jai le même problème en JRuby). Du moins tant que je nai pas creusé un peu plus.

Jai sûrement du faire une erreur quelque part, oublier quelque chose, ou faire quelque chose de travers. Si quelquun lit cela et à une idée, merci den men parler, je suis preneur !.

Si cest un comportement souhaité, jaimerais comprendre pourquoi, et si cest un oubli ou une erreur, jaimerais bien aider à trouver une solution.

ps: Retour au thème Scribbish que je trouve plus lisible, en attendant que je refasse quelque chose...