Skip to content
This repository has been archived by the owner on Jan 28, 2023. It is now read-only.

siriproxy plugin initialization #485

Open
elvisimprsntr opened this issue Mar 16, 2013 · 2 comments
Open

siriproxy plugin initialization #485

elvisimprsntr opened this issue Mar 16, 2013 · 2 comments

Comments

@elvisimprsntr
Copy link
Collaborator

Beginning with SP 0.4.2 (with the new plugin_init), I have observed a problem where code in the initialization section gets run upon start of siriproxy server, not just upon a siri connection. Perhaps it has always been this way, but it was presenting a challenge with one of my plugins which I was implementing auto discovery. I was able to work around the issue by making all initialization class variables and removed them from the initialization section. I tried to use the new plugin_init, but it seems to make initialization more difficult to understand and manage. Perhaps I did not fully grasp how to use the new plugin_init method. Not sure if anyone else has observed or has similar problems.

require 'dnssd'
require 'socket'
require 'httparty'
require 'yaml'

class SiriProxy::Plugin::RedEye < SiriProxy::Plugin

class Rest
include HTTParty
format :xml
end

####### Initialization

@@REIP = Hash.new
DNSSD.browse '_tf_redeye._tcp.' do |reply|
puts "[Info - Redeye] Bonjour discovery: " + reply.name
addr = Socket.getaddrinfo(reply.name + ".local.", nil, Socket::AF_INET)
@@REIP[reply.name] = addr[0][2]
end

begin
@@default = YAML.load(File.read(File.expand_path(File.dirname( FILE ) + "/reDefault.yml")))
@@stationID = YAML.load(File.read(File.expand_path(File.dirname( FILE ) + "/reStation.yml")))
rescue
puts "[Warning - RedEye] Error reading reDefault.yml and/or reStation.yml file."
end

begin
@@Resel = YAML.load(File.read(File.expand_path(File.dirname( FILE ) + "/reSel.yml")))
@@redeyeIP = YAML.load(File.read(File.expand_path(File.dirname( FILE ) + "/reRedeye.yml")))
@@roomid = YAML.load(File.read(File.expand_path(File.dirname( FILE ) + "/reRoom.yml")))
@@deviceid = YAML.load(File.read(File.expand_path(File.dirname( FILE ) + "/reDevice.yml")))
@@activityID = YAML.load(File.read(File.expand_path(File.dirname( FILE ) + "/reActivity.yml")))
@@commandID = YAML.load(File.read(File.expand_path(File.dirname( FILE ) + "/reCommand.yml")))
@@cmdURL = @@redeyeIP[@@Resel["redeye"]] + @@roomid[@@Resel["redeye"]][@@Resel["room"]] + @@deviceid[@@Resel["room"]][@@Resel["device"]]
rescue
@@Resel = @@default
@@redeyeIP = Hash.new
@@roomid = Hash.new { |h,k| h[k] = Hash.new }
@@deviceid = Hash.new { |h,k| h[k] = Hash.new }
@@activityID = Hash.new { |h,k| h[k] = Hash.new }
@@commandID = Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)}))
puts "[Warning - RedEye] Plugin not initialized. Say RedEye Initialize."
end

def initialize(config)
# Unfortunately, anything put here gets run during SiriProxy >= 0.4.2 startup.
end

@plamoni
Copy link
Owner

plamoni commented Mar 17, 2013

This was on purpose. Previously, there were two options for when you run your code: When there's a match with a listener or when the plugin gets loaded. The former happens when the plugin will be used, while the latter happens no matter what the user connected for. So anything "heavy" that has to happen in there happens all the time and not until the user connects.

With 0.4.2, initialization code now gets run when the server starts up, so heavy lifting can happen then (and objects can be persisted). For instance, you could maintain a connection to a service. If you want to do per-message connections to a service, those should be done in the listeners.

Essentially, you couldn't run code only once from a plugin before. Now you can. Sorry if it broke something, but I think this is a better approach to initialization code and allows for options that weren't there before.

I could probably add a method for getting called each time the plugin is loaded. But I'm a bit worried it might get abused and cause slowness in other plugins. I'll consider it.

@elvisimprsntr
Copy link
Collaborator Author

A couple of the problems I encountered were:

  1. Outside of initialize, you cannot call other methods. it will result in a "undefined variable" For example:

    rescue
    @@Resel = @@default
    @@redeyeIP = Hash.new
    @@roomid = Hash.new { |h,k| h[k] = Hash.new }
    @@deviceid = Hash.new { |h,k| h[k] = Hash.new }
    @@activityID = Hash.new { |h,k| h[k] = Hash.new }
    @@commandID = Hash.new(&(p=lambda{|h,k| h[k] = Hash.new(&p)}))
    init_redeyes # this results in undefined variable.
    end

  2. I can call methods inside initialize, but if I perform an if check on a variable/hash to perform other steps first, any call outside of the if check actually gets executed first. Example:

    def initialize(config)
    if @@redeyeIP.nil?
    init_redeyes
    end
    init_url # this actually gets run before the init_redeyes
    end

Not sure if it's a Ruby thing or something else, but stripping everything outside of initialize and making them class variables was the only way I could make work. Compared to getting Bonjour auto discovery working, getting initialization working was much more difficult.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants