Использование процессорных мощностей посетителей сайта. Паразитические вычисления.

Posted on March 04, 2009
Практически все современные браузеры обладают возможностью довольно быстро исполнять javascript.
Благодаря этому появилась возможность использовать посетителей сайта как ноды кластера для обсчета больших массивов данных.
Такое явление называется паразитическими вычислениями. Естественно что алгоритм должен быть хорошо параллелящимся и отдельные части вычисления должны проходить достаточно быстро.
Примером таких вычислений может быть обсчет матриц (нахождение определителя) или подсчет md5 хешей.
Так-же, поскольку все происходит без нашего контроля (обсчет на клиентских машинах) необходимо проверять результат вычисления. Одним из способов может быть сравнение нескольких результатов от разных нод с целью определить какое правильное методом "голосования".
Для примера я написал простое приложение которое обсчитывает md5 хеши.
Приложение расположено по адресу http://parasite.tumalevich.pp.ru/index.html.

Рассмотрим работу скрипта "паразита".
После инициализации он забирает с сервера список задач. В данном случае массив со строками.
После чего устанавливает интервал на то, что-бы раз в 500 миллисекунд обработать одну задачу и отправить ее на сервер.
После того, как список опустошится все повторяется сначала. Результат действия можно наблюдать в таблице в которую выводится результат.

В целом данный способ показывает, что в определенных случаях пользователей сайта можно использовать как облачный кластер для цифромололки.

Яваскрипт в ruby

Posted on May 21, 2008
Благодаря новому расширению Johnson в руби появилась возможность использовать javascript со всеми его возможностями.
Например

require 'rubygems'
require 'johnson'

context = Johnson::Context.new
context['alert'] = lambda { |x| puts x }
context.evaluate('alert("Hello ruby!");')

В примере в контексте javascript процесса создается функция alert и вызывается при обработке js скрипта.
Так-же возможен и обратный вызов

require 'rubygems'
require 'johnson'

def alert(arg)
  puts arg
end

context = Johnson::Context.new
context.evaluate('Ruby.alert("Hello ruby!")')
Так-же возможно таскать объекты из контеста в контекст

A = Struct.new(:foo)

context= Johnson::Context.new
context['alert'] = lambda { |x| puts x }
context['a'] = A.new("bar")
context.evaluate('alert(a.foo);') # => 'bar' 
Если надо использовать символ например для того что-бы записать User.find(:all) то используется Johnson.symbolize

context= Johnson::Context.new
context['alert'] = lambda { |x| puts x }
context.evaluate(<<-END
             for(var user in Ruby.User.find(Johnson.symbolize('all'))) {
               alert(user.first_name());
             }
             END
            )
Узнано благодаря RubyFlow из блога Aaron Patterson`a

Множественный аплоад файлов с помощью Acts As Attachment

Posted on August 11, 2007
Иногда с одной формы необходимо закачать несколько файлов сразу ... Недавно мне пришлось столкнуться с этой проблемой для написания простенькой текстовой CMS.
Был выбран acts_as_attachment (я его люблю) и написано небольшое количество кода.
Во первых, в страницу для закачки был вставлен яваскрипт который динамически добавлял, удалял поля типа файл:

<script type="text/javascript">
  var file_index = 0;
function add_file()
{
  var smb = document.createElement("input");
  smb.type = "file";
  smb.name = "file[" + file_index + "]";
  smb.id = "file_" + file_index;
  document.getElementById("files").appendChild(smb);
  var a = document.createElement("a");
  a.href = "javascript:remove_file(" + file_index + ");";
  a.id = "remove_file_" + file_index;
  a.appendChild(document.createTextNode("Удалить"));
  document.getElementById("files").appendChild(a);
  var br = document.createElement("br");
  br.id = "br_file_" + file_index;
  document.getElementById("files").appendChild(br);
  file_index++;
}

function remove_file(id)
{
  var container = document.getElementById("files");
  var input_f = document.getElementById("file_" + id);
  var a = document.getElementById("remove_file_" + id);
  var br = document.getElementById("br_file_" + id);
  container.removeChild(input_f);
  container.removeChild(a);
  container.removeChild(br);
}

</script>
При вызове add_file внутрь дива с id "files" добавляется новый набор из поля воода, ссылки на удаление этого поля и переноса строки.
В код контроллера был вставлен следующий фрагмент для обработки:

      params[:file].each do |f|
        p = Hash["attachment" => {"uploaded_data" => ""}]
        p["attachment"]["uploaded_data"] = f[1]
        att = Attachment.create!p["attachment"]
        @page.attachments << att
      end
Конечно обработки на правильность файлов нет, но добавить её дело 2х минут

установил highlight.js

Posted on February 05, 2007
Надоело писать неразборчивый код :)

def hello
return "world!"
end