How do I ensure that File.write finished?

Discussion in 'Ruby' started by Emil Kampp, Dec 10, 2009.

  1. Emil Kampp

    Emil Kampp Guest

    Hi there.

    I am trying to make a form to update the values in a yml file (my
    applications configuration file). This is working kind of fine.
    Sometimes it works, sometimes not.

    I have confirmed (through logging) that a content for +string+ is always
    there. So there is always something trying to be written into the yml
    file, but still sometimes it ends up being empty. And an empty
    configuration file is no good!

    Code:
    # server-controller (user generated controller in rails)
    def update
    # This inserts a new setting into the hash
    unless params[:new_setting][:key].blank? and
    params[:new_setting][:value].blank?
    params[:settings].collect{ |env, settings|
    settings[params[:new_setting][:key].to_sym] =
    params[:new_setting][:value].to_s }
    end
    
    # This writes the hash to the file (See the second snippet for
    details)
    ServerSystem::update_configuration(params[:settings])
    
    # Redirects to the action that restarts the server to load the new
    configurations
    redirect_to admin_server_restart_path
    end
    
    Code:
    # Custom class
    def update_configuration(settings)
    string = settings.to_yaml
    File.new(APP_CONFIG_FILE, "w").write string
    end
    
    The problem is that the setup is dodgy, sometimes it works, sometimes it
    looks like the server is restarted before the content of +string+ is
    written to the configuration file.
    How can I ensure that the content has been written before executing next
    line of code (the restart in this case)?
    --
    Posted via http://www.ruby-forum.com/.
     
    Emil Kampp, Dec 10, 2009
    #1
    1. Advertising

  2. On Thursday 10 December 2009, Emil Kampp wrote:
    > |Hi there.
    > |
    > |I am trying to make a form to update the values in a yml file (my
    > |applications configuration file). This is working kind of fine.
    > |Sometimes it works, sometimes not.
    > |
    > |I have confirmed (through logging) that a content for +string+ is always
    > |there. So there is always something trying to be written into the yml
    > |file, but still sometimes it ends up being empty. And an empty
    > |configuration file is no good!
    > |
    > |
    Code:
    > |# server-controller (user generated controller in rails)
    > |  def update
    > |    # This inserts a new setting into the hash
    > |    unless params[:new_setting][:key].blank? and
    > |params[:new_setting][:value].blank?
    > |      params[:settings].collect{ |env, settings|
    > |settings[params[:new_setting][:key].to_sym] =
    > |params[:new_setting][:value].to_s }
    > |    end
    > |
    > |    # This writes the hash to the file (See the second snippet for
    > |details)
    > |    ServerSystem::update_configuration(params[:settings])
    > |
    > |    # Redirects to the action that restarts the server to load the new
    > |configurations
    > |    redirect_to admin_server_restart_path
    > |  end
    > |
    > |
    > |
    Code:
    > |# Custom class
    > |    def update_configuration(settings)
    > |      string = settings.to_yaml
    > |      File.new(APP_CONFIG_FILE, "w").write string
    > |    end
    > |
    > |
    > |The problem is that the setup is dodgy, sometimes it works, sometimes it
    > |looks like the server is restarted before the content of +string+ is
    > |written to the configuration file.
    > |How can I ensure that the content has been written before executing next
    > |line of code (the restart in this case)?
    > |


    I'm not sure, but maybe the fact you're not closing the file after writing has
    something to do with that. Try replacing the last line of update_configuration
    with:

    File.open(APP_CONFIG_FILE, 'w'){|f| f.write string}

    When given a block, File.open closes the file after calling the block, which
    should ensure that everything you wrote to file should have actually been
    written.

    I hope this helps

    Stefano
     
    Stefano Crocco, Dec 10, 2009
    #2
    1. Advertising

  3. 2009/12/10 Stefano Crocco <>:
    > On Thursday 10 December 2009, Emil Kampp wrote:
    >> |Hi there.
    >> |
    >> |I am trying to make a form to update the values in a yml file (my
    >> |applications configuration file). This is working kind of fine.
    >> |Sometimes it works, sometimes not.
    >> |
    >> |I have confirmed (through logging) that a content for +string+ is alway=

    s
    >> |there. So there is always something trying to be written into the yml
    >> |file, but still sometimes it ends up being empty. And an empty
    >> |configuration file is no good!
    >> |
    >> |
    Code:
    >> |# server-controller (user generated controller in rails)
    >> | =A0def update
    >> | =A0 =A0# This inserts a new setting into the hash
    >> | =A0 =A0unless params[:new_setting][:key].blank? and
    >> |params[:new_setting][:value].blank?
    >> | =A0 =A0 =A0params[:settings].collect{ |env, settings|
    >> |settings[params[:new_setting][:key].to_sym] =3D
    >> |params[:new_setting][:value].to_s }
    >> | =A0 =A0end
    >> |
    >> | =A0 =A0# This writes the hash to the file (See the second snippet for
    >> |details)
    >> | =A0 =A0ServerSystem::update_configuration(params[:settings])
    >> |
    >> | =A0 =A0# Redirects to the action that restarts the server to load the =[/color][/color]
    new[color=blue][color=green]
    >> |configurations
    >> | =A0 =A0redirect_to admin_server_restart_path
    >> | =A0end
    >> |
    >> |
    >> |
    Code:
    >> |# Custom class
    >> | =A0 =A0def update_configuration(settings)
    >> | =A0 =A0 =A0string =3D settings.to_yaml
    >> | =A0 =A0 =A0File.new(APP_CONFIG_FILE, "w").write string
    >> | =A0 =A0end
    >> |
    >> |
    >> |The problem is that the setup is dodgy, sometimes it works, sometimes i=

    t
    >> |looks like the server is restarted before the content of +string+ is
    >> |written to the configuration file.
    >> |How can I ensure that the content has been written before executing nex=

    t
    >> |line of code (the restart in this case)?
    >> |

    >
    > I'm not sure, but maybe the fact you're not closing the file after writin=

    g has
    > something to do with that.


    That's definitively the reason.

    > Try replacing the last line of update_configuration
    > with:
    >
    > File.open(APP_CONFIG_FILE, 'w'){|f| f.write string}
    >
    > When given a block, File.open closes the file after calling the block, wh=

    ich
    > should ensure that everything you wrote to file should have actually been
    > written.


    [ADV]: see also
    http://blog.rubybestpractices.com/posts/rklemme/001-Using_blocks_for_Robust=
    ness.html

    Cheers

    robert


    --=20
    remember.guy do |as, often| as.you_can - without end
    http://blog.rubybestpractices.com/
     
    Robert Klemme, Dec 10, 2009
    #3
  4. Emil Kampp

    Roger Pack Guest

    > File.new(APP_CONFIG_FILE, "w").write string

    This file is never closed, so if the process is exited without running
    its finalizers for some reason, buffered data could be lost.

    -r
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, Dec 10, 2009
    #4
  5. Emil Kampp

    Emil Kampp Guest

    Emil Kampp, Dec 10, 2009
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Peter A. Schott
    Replies:
    0
    Views:
    929
    Peter A. Schott
    Feb 10, 2005
  2. Darius
    Replies:
    3
    Views:
    666
    kwikius
    May 20, 2006
  3. Replies:
    5
    Views:
    338
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=
    Jan 23, 2007
  4. writeson
    Replies:
    8
    Views:
    313
    Ethan Furman
    Jul 14, 2008
  5. seafoid
    Replies:
    2
    Views:
    329
    seafoid
    Dec 18, 2009
Loading...

Share This Page