librelist archives

« back to archive

Green Shoes: memory issues

Green Shoes: memory issues

From:
Ola Leifler
Date:
2013-04-24 @ 18:27
Hi!

I've noticed that replacing the contents of a stack repeatedly will leak 
memory and lead to the application running out of memory or else not 
updating the GUI. Below is sample code that makes green shoes crash after 
800-900 iterations on my machine. Can anyone else reproduce this?

/Ola

# -*- coding: utf-8 -*-
require 'green_shoes'
require 'optparse'

class Conf
  class << self
    attr_accessor :server, :db, :username, :password, :file_name

    def product_name
      "My product"
    end

    def product
      options[:product] || "product"
    end

    def server
      @server ||= options[:server]
    end

    def db
      @db ||= options[:db]
    end

    def username
      @username ||= options[:username]
    end

    def password
      @password ||= options[:password]
    end

    def sspi?
      options[:sspi]
    end

    def batch?
      options[:batch]
    end
    
    def backup_dir
      Etc.systmpdir
    end

    def sql_dir
      "."
    end

    def options
      @options ||= {}
      # Ignore command line arguments when running this script as a
      # standalone executable compiled by Ocra, in which case the
      # environment variable OCRA_EXECUTABLE is set to $0
      if @options.empty? && !ENV["OCRA_EXECUTABLE"]
        OptionParser.new do |opts|
          opts.banner = "Usage: ruby #{__FILE__} [options]"      
          opts.on("-p", "--product PRODUCT", "Select product") do |p|
            options[:product] = p
          end
          opts.on("-s", "--server SERVER", "Select server") do |p|
            options[:server] = p
          end
          opts.on("-d", "--database DATABASE", "Select database") do |p|
            options[:db] = p
          end
          opts.on("-u", "--username USERNAME", "SQL Server username") do |p|
            options[:username] = p
          end
          opts.on("-P", "--password PASSWORD", "SQL Server password") do |p|
            options[:password] = p
          end
          opts.on("-E", "--sspi", "Use Windows Authentication (SSPI)") do |p|
            options[:sspi] = true
          end
          opts.on("-b", "--batch", "Upgrade and close immediately") do |p|
            options[:batch] = true
          end
        end.parse!
      end
      @options
    end

  end
end

class Shoes
  class App   
    def icon filename=nil
      filename.nil? ? win.icon : win.icon = filename
      Gtk::Window.set_default_icon(win.icon)
    end
  end
end

# Only call Gtk.main_quit once to avoid warnings or errors related to
# "no Gtk main loop running"
class << Gtk; attr_accessor :running; end

class Object

  # Make sure Green Shoes does not crash on exit when exit is called with status
  def exit(status=true)
    if Gtk.running
      Gtk.running=false
      Gtk.main_quit
      File.delete Shoes::TMP_PNG_FILE if File.exist? Shoes::TMP_PNG_FILE
    end
  end
  
  # Override Green Shoes "confirm" method to provide dialog with a custom title
  def confirm title, msg
    $dde = true
    dialog = Gtk::Dialog.new(
      title, 
      get_win,
      Gtk::Dialog::MODAL | Gtk::Dialog::DESTROY_WITH_PARENT,
      [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT],
      [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT]
    )
    dialog.vbox.add Gtk::Label.new msg
    dialog.set_size_request 500, 100
    dialog.show_all
    ret = dialog.run == Gtk::Dialog::RESPONSE_ACCEPT
    dialog.destroy
    ret
  end

end

class DbUpgrade

  class << self
    def create(conf,product)
      new(conf,product)
    end
  end

  attr_accessor :callback, :num_upgrade_files

  def initialize(conf,product)
    @num_upgrade_files=1_500
  end

  def run
    # Mockup DB updater
    @num_upgrade_files.times do |i| 
      callback.call "#{i}_upgrade.sql" if callback
      sleep 0.05
    end
  end

end

class UpgradeGUI < Shoes
  url "/", :select
  url "/progress", :progress_window

  def current_setting
    "'#{Conf.server}/#{Conf.db}' for #{Conf.product_name}"
  end
  
  def initialize
    @step=0
    Gtk.running=true
  end

  def select
    background rgb(70,21,107)
    # Skip the form if command line parameters are provided
    if Conf.server && 
        Conf.db && 
        (Conf.sspi? || (Conf.username && Conf.password))
      visit "/progress"
    end
    flow do
      # Absolute positioning seems necessary here, why?
      stack left: 10, top: 100 do
        para "Server"
        @server = edit_line
        @server.text=Conf.server if Conf.server
        para "DB"
        @db = edit_line
        @db.text=Conf.db if Conf.db

        authentication_form

        button "Upgrade" do       
          Conf.server=@server.text
          Conf.db=@db.text
          if ! @use_sspi.checked?
            Conf.username=@username.text
            Conf.password=@password.text
          end
          if confirm("Confirm upgrade", 
                     "Upgrade DB #{current_setting}?")
            visit "/progress"
          end
        end
      end
    end
  end

  def progress_window
    
    background rgb(70,21,107)
    stack do
      para "Upgrading the DB #{current_setting}"
      @upgrade_file=stack { para "..." }
      # Absolute positioning seems necessary here, why?
      @p = progress top: 300, left: 50, width: 400
      
    end # stack
    
    run_upgrade
    
  end # progress_window

  def run_upgrade
    upgrader = DbUpgrade.create Conf, Conf.product
    @num_steps = upgrader.num_upgrade_files
    upgrader.callback = lambda do |file|
      @step+=1
      @update_file_name = file
    end
    @upgrade_thread=Thread.new { upgrader.run }
    
    @animate = animate do
      @p.fraction = @step / @num_steps.to_f
      update_name @update_file_name
      if @p.fraction==1.0
        finish_upgrade
      end # if              
    end # animate

  end

  def username_password
    para "Username"
    @username = edit_line
    @username.text=Conf.username if Conf.username
    para "Password"
    @password = edit_line :secret => true
    @password.text=Conf.password if Conf.password
  end

  def para(text)
    # there seems to be a bug related to setting font styles, so I
    # cannot set styles on a slot but must set it on all elements
    super text, stroke: white, family: "Calibri"
  end

  def authentication_form
    flow do
      para "Windows authentication"
      @use_sspi = check do |c|
        if ! c.checked?
          @user_pwd.append do
            stack do
              username_password
            end
          end
        else
          @user_pwd.clear
        end
      end
      @use_sspi.checked=Conf.sspi?
      # Hide the username/password form if Windows authentication is
      # to be used
      @user_pwd = @use_sspi.checked? ? stack : stack { username_password }
    end
  end

  def update_name(name)
    @upgrade_file.clear
    @upgrade_file.append  { para name }
  end

  def finish_upgrade
    @animate.stop
    @upgrade_thread.join

    # Quit immediately when invoked by Ocra, so we can compile
    # this script without manual intervention
    
    if Conf.batch?
      exit
    end

    update_name "Done!"
    flow do
      # Absolute positioning seems necessary here due to layout 
limitations for progress bars
      button "Close", top: 400, left: 150  do
        exit
      end
    end # flow 
    
  end
  
end

if $0 == __FILE__
  Shoes.app(title: "DB Upgrade tool for #{Conf.product_name}", 
            width: 400, 
            height: 500)
end


 

Re: [shoes] Green Shoes: memory issues

From:
Sebastjan Hribar
Date:
2013-04-24 @ 18:39
Dne 24. 04. 2013 20:27, piše Ola Leifler:
> Hi!
>
> I've noticed that replacing the contents of a stack repeatedly will leak
memory and lead to the application running out of memory or else not 
updating the GUI. Below is sample code that makes green shoes crash after 
800-900 iterations on my machine. Can anyone else reproduce this?
>
> /Ola
>
Hi Ola,

the break point occured after 650 for me. But it seemed unstable even 
before that.

kind regards
seba

Re: [shoes] Green Shoes: memory issues

From:
ashbb
Date:
2013-04-25 @ 13:31
Hi Ola, Seba and folks,

I reproduced "not updating the GUI" at 1055 iterations on my Windows 7.
But after replaced the line 148 of Ola's code like this:

  sleep 0.05 ----> `sleep 0.01` or `puts i`

I could finish all 1500 iterations.
Umm,... I couldn't figure out this is a Green Shoes problem or not...

ashbb

Re: [shoes] Green Shoes: memory issues

From:
J. Kaiden
Date:
2013-04-25 @ 23:15
hi Ola,

  i feel stupid,  but - how do i test this?  looks cool - what do i need to
enter in all the fields to try this out?

- j


On Thu, Apr 25, 2013 at 3:31 PM, ashbb <ashbbb@gmail.com> wrote:

> Hi Ola, Seba and folks,
>
> I reproduced "not updating the GUI" at 1055 iterations on my Windows 7.
> But after replaced the line 148 of Ola's code like this:
>
>   sleep 0.05 ----> `sleep 0.01` or `puts i`
>
> I could finish all 1500 iterations.
> Umm,... I couldn't figure out this is a Green Shoes problem or not...
>
> ashbb
>
>

Re: [shoes] Green Shoes: memory issues

From:
Sebastjan Hribar
Date:
2013-04-26 @ 05:02
Dne 26. 04. 2013 01:15, piše J. Kaiden:
> hi Ola,
>
>   i feel stupid,  but - how do i test this?  looks cool - what do i 
> need to enter in all the fields to try this out?
>
> - j
>
hi j,

I've just entered some random stuff...

regards
seba

Re: [shoes] Green Shoes: memory issues

From:
J. Kaiden
Date:
2013-04-26 @ 19:15
@Seba - thanks!  like i said, i feel dumb ;)

@Ola - using Ubuntu 12.04, ruby 2.0, green shoes 1.1.373, things hung up at
261 iterations until i changed the code as ashbb suggested - then it made
it through with no problems.


On Fri, Apr 26, 2013 at 7:02 AM, Sebastjan Hribar <
sebastjan.hribar@gmail.com> wrote:

> Dne 26. 04. 2013 01:15, piše J. Kaiden:
> > hi Ola,
> >
> >   i feel stupid,  but - how do i test this?  looks cool - what do i
> > need to enter in all the fields to try this out?
> >
> > - j
> >
> hi j,
>
> I've just entered some random stuff...
>
> regards
> seba
>

Re: [shoes] Green Shoes: memory issues

From:
Sebastjan Hribar
Date:
2013-04-26 @ 19:23
Dne 26. 04. 2013 21:15, piše J. Kaiden:
> @Seba - thanks!  like i said, i feel dumb ;)
>

lol, I am pretty sure I still hold the 1st place in that department:)

> @Ola - using Ubuntu 12.04, ruby 2.0, green shoes 1.1.373, things hung 
> up at 261 iterations until i changed the code as ashbb suggested - 
> then it made it through with no problems.
>
>
> On Fri, Apr 26, 2013 at 7:02 AM, Sebastjan Hribar 
> <sebastjan.hribar@gmail.com <mailto:sebastjan.hribar@gmail.com>> wrote:
>
>     Dne 26. 04. 2013 01 <tel:26.%2004.%202013%2001>:15, piše J. Kaiden:
>     > hi Ola,
>     >
>     >   i feel stupid,  but - how do i test this?  looks cool - what do i
>     > need to enter in all the fields to try this out?
>     >
>     > - j
>     >
>     hi j,
>
>     I've just entered some random stuff...
>
>     regards
>     seba
>
>