Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/json_hash_file.rb
Views: 11766
# -*- coding => binary -*-12require 'json'3require 'fileutils'45#6# This class provides a thread-friendly hash file store in JSON format7#8module Rex9class JSONHashFile1011attr_accessor :path1213def initialize(path)14self.path = path15@lock = Mutex.new16@hash = {}17@last = 018end1920def [](k)21synced_update22@hash[k]23end2425def []=(k,v)26synced_update do27@hash[k] = v28end29end3031def keys32synced_update33@hash.keys34end3536def delete(k)37synced_update do38@hash.delete(k)39end40end4142def clear43synced_update do44@hash.clear45end46end4748private4950# Save the file, but prevent thread & process contention51def synced_update(&block)52@lock.synchronize do53::FileUtils.mkdir_p(::File.dirname(path))54::File.open(path, ::File::RDWR|::File::CREAT) do |fd|55fd.flock(::File::LOCK_EX)5657# Reload and merge if the file has changed recently58if fd.stat.mtime.to_f > @last59parse_data(fd.read).merge(@hash).each_pair do |k,v|60@hash[k] = v61end62end6364res = nil6566# Update the file on disk if new data is written67if block_given?68res = block.call69fd.rewind70fd.write(JSON.pretty_generate(@hash))71fd.sync72fd.truncate(fd.pos)73end7475@last = fd.stat.mtime.to_f7677res78end79end80end8182def parse_data(data)83return {} if data.to_s.strip.length == 084begin85JSON.parse(data)86rescue JSON::ParserError => e87elog("JSONHashFile at #{path} was corrupt", error: e)88{}89end90end9192end93end949596