Class Models for Lua

# Thread Scheduler with Sockets

## `loop.thread.SocketScheduler`

Subclass of `IOScheduler` that includes an integrated instance of `CoSocket` to provide a socket API. This class is simply a shortcut for the creation of a thread scheduler with an integrated socket API using the classes provided in the `loop.thread` package.

Each instance contains an integrated instance of `CoSocket` and defines the fields required by `IOScheduler` using functions provided by LuaSocket library.

## Behavior

### Initialization

`SocketScheduler([object])`
  Makes `object` an instance of `SocketScheduler` associating it with an instance of `CoSocket`.

### Fields

`time`
  Field used by superclass `Scheduler`. The default value of this field is redefined to the `socket.gettime` function of the LuaSocket library.
`select`
  Field required by superclass `IOScheduler`. The default value of this field is defined to the `socket.select` function of the LuaSocket library.
`sleep`
  Field required by superclass `IOScheduler`. The value of this field is defined to the `socket.sleep` function of the LuaSocket library.

## Remarks

- This class can be used as an instance of itself, therefore all methods can be executed over the class itself.

## Examples

### Script Execution Server

    --------------------------------------------------------------------------------
    -- Server Script ---------------------------------------------------------------

    local oo        = require "loop.base"
    local scheduler = require "loop.thread.SocketScheduler"
    local socket    = scheduler.socket

    local Env = oo.class{ __index = _G }

    scheduler:register(coroutine.create(function()
      local port = socket:bind("localhost", 2809)
      local channel, errmsg
      repeat
        channel, errmsg = port:accept()
        if channel then
          local chunk, errmsg = channel:receive()
          if chunk then
            chunk, errmsg = loadstring(chunk)
            if chunk then
              setfenv(chunk, Env{ channel = channel })
              chunk = coroutine.create(chunk)
              scheduler:register(chunk)
              scheduler.traps[chunk] = function(thread, success, errmsg)
                if not success then
                  -- trap is executed outside a scheduled co-routine
                  -- therefore the call is made over the original
                  -- socket provided by LuaSocket library.
                  channel.__object:send(errmsg)
                  channel.__object:close()
                end
              end
            end
          end
          if errmsg then
            channel:send(errmsg)
            channel:close()
          end
        end
      until errmsg
      port:close()
    end))

    scheduler:run()

    --------------------------------------------------------------------------------
    -- Client Script ---------------------------------------------------------------

    local socket = require "socket"

    local script = [[
      local name = os.tmpname()
      os.execute("dir C: > "..name)
      local file = io.open(name)
      channel:send(file:read("*a"))
      file:close()
      os.remove(name)
      channel:close()
    ]]

    local channel = assert(socket.connect("localhost", 2809))
    assert(channel:send(script:gsub("\n", " ").."\n"))
    print(assert(channel:receive("*a")))

Copyright (C) 2004-2008 Tecgraf, PUC-Rio

This project is currently being maintained by Tecgraf at PUC-Rio.