1

I am using the "lists" widget in dashing to display a string and a value (in this case the name of the user and number of jobs running on the batch system).

I would like this displayed sorted by value (number of jobs) in descending order. It currently reads these in from a csv file that contains the string (username) and value (number of jobs), sorted in descending order.

CSV.foreach('/path/to/file.csv') do |row|
    user = row[0]
    numberOfJobs = row[1]
    SGE_list[user] =  { label: user, value: numberOfJobs }
end

As soon as dashing starts, and reads the file for the first time, this is correct. However when it re-reads the file (which is continuously updated) then it keeps the original order, (regardless of the order in the csv file).

Any suggestions?

Full jobs file:

require 'csv'

JOB_list = Hash.new({ value: 0 })

SCHEDULER.every '5m' do

  groups = ["user1", "user2", "user3", "user4", "user5", "user6", "user7", "user8"]

  # Read in to get order                                                        
  CSV.foreach('/opt/dashing/sweet_dashboard_project/jobs/qusage.csv') do |row|
    user = row[0]
    numberOfJobs = row[1]
    JOB_list[user] =  { label: user, value: numberOfJobs }
  end

  # blank all values                                                            
  for g in groups
    JOB_list[g] =  { label: g, value: 0 }
  end

  CSV.foreach('/opt/dashing/sweet_dashboard_project/jobs/qusage.csv') do |row|
    user = row[0]
    numberOfJobs = row[1]
    JOB_list[user] =  { label: user, value: numberOfJobs }
  end

  send_event('batch_jobs', { items: JOB_list.values })

end

The csv file can vary. it could be: user7, 1000 user2, 987 user8, 800 user6, 400 user5, 200 user4, 122 user1, 89 user3, 2

or, if the user is not running a job, they are not listed so:

user6, 340 user5, 123 user4, 101

it is always sorted by the 2nd column.

user26582
  • 11
  • 1
  • 3

2 Answers2

0

Seems like your hash order becomes "burned in" sorted by [user].

Hashes enumerate their values in the order that the corresponding keys were inserted. http://www.ruby-doc.org/core-2.1.2/Hash.html

Therefore "emptying" the values won't cure this. You could add some sorting to your hash. But if you trust the sorting in your CSV, and it loads correctly with a new Hash object, why not reinitialize the Hash every run? Quick & Easy

require 'csv'


SCHEDULER.every '5m' do

  JOB_list = Hash.new

  # Trust the CSV file to sort by row[1], a.k.a. NumberOfJobs                                                        
  CSV.foreach('/opt/dashing/sweet_dashboard_project/jobs/qusage.csv') do |row|
    user = row[0]
    numberOfJobs = row[1]
    JOB_list[user] =  { label: user, value: numberOfJobs }
  end

  send_event('batch_jobs', { items: JOB_list.values })

end
0

I'd recommend deleting the widget data before repopulating it. Just before the send_event in your script, you could add this line:

Sinatra::Application.settings.history.delete('batch_jobs')

This will erase the widget hash you're working with, without sending an update to any dashboards that are using the widget. Since you're immediately repopulating it, the widget will get the update from that, which will then display the new (and newly sorted) list.

It's not elegant, but it should work for you.