<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Beyond the Void &#187; COGS</title>
	<atom:link href="http://www.byvoid.com/blog/tag/cogs/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.byvoid.com/blog</link>
	<description></description>
	<lastBuildDate>Tue, 29 Jun 2010 08:44:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Vakuum开发笔记01 开天辟地</title>
		<link>http://www.byvoid.com/blog/vakuum-dev-note-01/</link>
		<comments>http://www.byvoid.com/blog/vakuum-dev-note-01/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 07:24:01 +0000</pubDate>
		<dc:creator>BYVoid</dc:creator>
				<category><![CDATA[設計開發]]></category>
		<category><![CDATA[COGS]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[OJ]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[vakuum]]></category>
		<category><![CDATA[设计]]></category>
		<category><![CDATA[评测系统]]></category>
		<category><![CDATA[通信]]></category>

		<guid isPermaLink="false">http://www.byvoid.com/blog/?p=1895</guid>
		<description><![CDATA[1.缘起 先驱——COGS 早在2008年，我自学PHP后开发了COGS，并成功用于学校内部的OJ，ruvtex。也曾经对外开放过，但是由于学校网络不稳定，后来一直连不上了。我还把COGS推荐给了OOJ，只是直到现... ]]></description>
			<content:encoded><![CDATA[<h3>1.缘起</h3>
<h4>先驱——COGS</h4>
<p>早在2008年，我自学PHP后开发了COGS，并成功用于学校内部的OJ，ruvtex。也曾经对外开放过，但是由于学校网络不稳定，后来一直连不上了。我还把COGS推荐给了OOJ，只是直到现在都过于冷清。随着COGS功能不断完善，体系越来越庞大，Bug也非常多。限于当时水平，架构非常混乱，以至于到无法继续维护的地步，于是我遗憾的宣布了COGS的死亡。随后我又萌生了一个重新设计的念头，只是高二时期忙于NOI和文化课的学习，这一计划就一直被搁置到NOI2009结束。</p>
<h4>知识准备</h4>
<p>NOI2009结束以后，我终于有了时间，可以进行我新的OJ的开发了。之前的COGS不敢开源，因为写的太烂，开源的话肯定会黑得万劫不复。不过新的OJ不同，为了提高对自己要求，我决定对其开源。</p>
<p>我在暑假时期阅读了有关PHP高级开发、MVC架构、Javascript、CSS、Linux系统编程等大量书籍。受到经典的架构Zend Framework的启发，起初决定用它开发，但是学习不久就发现Zend Framework过于庞大，学习难度太大，并且难以找到比较好的资料。在Zend Framework的官方网站上阅读纯英文的文档实在太费力了，而且效果不好，始终没有弄明白其本质。开源界有一个箴言，叫做“不要重新发明轮子”。什么意思呢？就是说很多开发人员总是在做一些前人已经做过，而且做得很好的工作。比如libxml2已经是一个非常优秀的C语言XML库了，你再自己写一个XML解析库，就是在浪费时间，尽管也许你做的不错，但也最多算的上是“重新发明了轮子”。起初我非常笃信这句“箴言”，拼死也要学Zend Framework，做了大量的无用功。但后来细细一想，我们最初学算法、数据结构的时候，不是都是要自己实现每一个细节吗？尽管库函数可能已经做得很好了，如qsort，平衡树。而我现在也是MVC架构的初学者，在对其理解不是很深刻的情况下，直接学习某个库、某个架构，是非常不明智的行为。因此我决定要“发明轮子”——自己开发一个合适的架构，就叫——BYVoid Framework Library（BFL）。</p>
<p>恰好当时父亲的公司准备建一个产品介绍性网站，为节约成本就把开发的任务交给了我。我想这是一个难得的练手的机会，决定用我的BFL开发。果然在开发的时候遇到了前所未有的问题，但是都一个个迎刃而解了，而且获得了不少经验，其中包括Apache2 .htaccess的设置。两个星期以后，<a href="http://www.cdxinwei.com/public/about" target="_blank">公司的网站</a>制作完成，我的&#8221;MVC架构轻量级内容管理系统&#8221;也发布了。</p>
<h3>2.Vakuum诞生之初与架构设计</h3>
<h4>命名</h4>
<p>2009年9月，我正式开始开发新的OJ。在开发先我想先起个名字——就像“没有名字的船不会带来好运”。起初准备叫vacuum，英语意思是“真空”，算是Beyond the Void的衍生。但是我不幸地发现这个名字已经在sourceforge上被占用了，后来决定改名为vakuum，即vacuum的德语拼写方法。</p>
<h4>基础结构</h4>
<p>Vakuum作为一个OJ，我把它剖分为了三个部分，vakuum-web，vakuum-judge和judger。<strong>vakuum-web</strong>是一个网站，用于和用户交互，处理各种请求，它是一个PHP网站，应该能够<strong>跨平台</strong>。<strong>vakuum-judge</strong>则是评测机终端，用于接收来自vakuum-web的评测任务，评测以后返回结果。而<strong>judger</strong>是评测的核心，其中包含编译器<strong>compiler</strong>、执行器<strong>executor</strong>和检查器<strong>checker</strong>三部分，分别用于编译用户程序、执行用户程序和比对用户输出与测试数据。<span style="text-decoration: underline;">简而言之，vakuum-web是一个用户与核心的中介，而vakuum-judge则是judger的通信接口。</span>我的目标是网站和评测分离，并允许多评测机协同工作，因此vakuum-web和vakuum-judge之间少不了通信。</p>
<h4>通信设计</h4>
<p>参考很多成熟OJ的结构，发现几乎都是把vakuum-judge模块实现为一个常驻进程daemon，不断检查数据库是否有新的任务出现，对其评测，但后写回数据库。多数设计都没有分离vakuum-web和judger，即限定了只能有一个评测机，少数可以实现分离，但是实际上是多写了一个通信程序。我的想法是vakuum-judge也用PHP实现，这样就避免了自己写一个socket通信程序，而且不需要额外获得底层权限以常驻进程。这样只需要接收来自vakuum-web的HTTP请求，对其处理，然后将结果写回。可是这样的一个同步传输方案有很大的问题，即vakuum-web发送请求以后需要长时间被阻塞在通信上，等待vakuum-judge评测的结束。如此一来加大了传输的风险，二来加重vakuum-web的服务器负载，三来还无法让用户看到评测的进度。因此我想出了一个异步传输方案，即vakuum-web只发送请求，完毕后就断开连接，之后等待vakuum-judge的回传即可。然而PHP有一个特性，就是用户浏览器断开连接以后，PHP脚本也会停止执行，vakuum-web是在模拟用户浏览器发送请求，断开链接以后就相当于浏览器按下了“停止”键，vakuum-judge正在执行的脚本不管到了哪里都会停止。查资料以后才知道PHP有这样的一个函数，ignore_user_abort()，忽略用户中止，就是用来对付这种情况的。</p>
<h4>队列处理</h4>
<p>通信方式设计很成功了，还有一个问题就是如何处理评测队列。这是一个棘手的问题，要么为什么有那么多大型OJ经常卡在评测队列上，出现Waiting长龙呢？几乎所有的OJ都是写了一个常驻进程的daemon处理队列。我想为了实现多评测机调度，这个daemon必须是现在vakuum-web端，但是这样就违背了我当初vakuum-web能够“跨平台”的设想，而且vakuum-web必须获得系统底层权限——不仅维护不便，还有安全隐患。</p>
<p>绞尽脑汁以后，我想出了“链式反应”的想法，其实也是受了通信设计方式的启发。这种方法不需要获得底层权限，不用额外写一个daemon，能够跨平台，不用为安全性额外操心，还可以充分利用先前写好的代码，究竟是什么方法呢？其实就是用一个PHP进程来充当队列处理器，这个队列处理器不需要常驻内存，仅仅在用时才会出现。就是当用户提交一个评测任务以后，如果有空闲评测机的话，立即对任务进行处理，然后当vakuum-judge返回评测完毕的信号时，vakuum-web端再对评测任务队列进行检查，看看有没有新的任务出现，如果有的话，立刻执行即可。这种方法很简洁，而且支持多评测机协同工作，因为每次结果返回时都要检查队列，就好像链式反应，或者多米诺骨牌一样，只要处理了第一个，后面的就都会接着被处理。</p>
<p>这种队列处理方法的唯一缺陷在于依赖评测机的返回信号，如果评测机那边出了什么问题，或者因为通信原因vakuum-web没有正常接收到信号，队列就会被卡住。因此首先需要保证的是vakuum-judge需要绝对的安全和稳定，除非无可抗拒理由（如网线被拔），不会因为任何原因而不正常返回信号。此外还要增加人工干预手段（如强制继续处理队列），避免真的不可抗拒原因的到来。</p>
<p>——————————————————————————————————</p>
<p>先到此为止，欢迎继续关注Vakuum开发笔记，下次将要写的是评测机核心(judger)的设计。目前的开发进度停滞在后台管理各种繁杂的细枝末节的处理上，下图的是目前的后台管理界面截图。</p>
<p><a href="http://www.byvoid.com/blog/wp-content/uploads/2010/04/vakuum.png"><img class="alignnone size-full wp-image-1896" title="vakuum" src="http://www.byvoid.com/blog/wp-content/uploads/2010/04/vakuum.png" alt="点击看全图" width="800" height="402" /></a></p>
<h3  class="related_post_title">Maybe you like</h3><ul class="related_post"><li><a href="http://www.byvoid.com/blog/vakuum-oj-dev/" title="开源的在线评测系统——Vakuum">开源的在线评测系统——Vakuum</a></li><li><a href="http://www.byvoid.com/blog/cmykrgb123-online-judge-system-testing/" title="CmYkRgB123 Online Judge System 比赛测试">CmYkRgB123 Online Judge System 比赛测试</a></li><li><a href="http://www.byvoid.com/blog/ubuntu-710-mysql-apache-php-proftpd-seup/" title="Ubuntu 7.10 + Mysql + Apache + PHP + ProFTPD 安装指导">Ubuntu 7.10 + Mysql + Apache + PHP + ProFTPD 安装指导</a></li><li><a href="http://www.byvoid.com/blog/vakuum-dev-note-02/" title="Vakuum开发笔记02 核心与安全问题">Vakuum开发笔记02 核心与安全问题</a></li><li><a href="http://www.byvoid.com/blog/cogs-plan/" title="在线评测系统发布计划">在线评测系统发布计划</a></li><li><a href="http://www.byvoid.com/blog/haoi2008-tmr/" title="明天就是省选">明天就是省选</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.byvoid.com/blog/vakuum-dev-note-01/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>还是Firefox执行脚本快</title>
		<link>http://www.byvoid.com/blog/firefox-js/</link>
		<comments>http://www.byvoid.com/blog/firefox-js/#comments</comments>
		<pubDate>Sun, 02 Nov 2008 11:45:18 +0000</pubDate>
		<dc:creator>BYVoid</dc:creator>
				<category><![CDATA[點滴發現]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[COGS]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[浏览器]]></category>

		<guid isPermaLink="false">http://www.byvoid.com/blog/?p=432</guid>
		<description><![CDATA[为COGS写了两个插件，IP地理位置查询和简繁转换，都是用Javascript实现的。做好以后分别用IE,Opera,Chrome和Firefox运行了一下。IE很慢，Opera和Chrome要卡一下，Firefox非常流畅，一点也不停顿。有人说F... ]]></description>
			<content:encoded><![CDATA[<p>为COGS写了两个插件，IP地理位置查询和简繁转换，都是用Javascript实现的。做好以后分别用IE,Opera,Chrome和Firefox运行了一下。IE很慢，Opera和Chrome要卡一下，Firefox非常流畅，一点也不停顿。有人说Firefox执行脚本最快，果然不是吹的。</p>
<p><a href="http://addons.sociz.com/firefox/531/">Firebug</a>真是太好用了，Javascript调试就靠它了，它还能显示Ajax操作。</p>
<p>IP查询插件的截图，登录后可以使用。<a href="http://www.ruvtex.cn/cogs/addons/ipquery/">http://www.ruvtex.cn/cogs/addons/ipquery/</a><br />
<a href="http://www.byvoid.com/blog/wp-content/uploads/2008/11/cogs_ipquery.png"><img class="alignnone size-thumbnail wp-image-433" title="COGS插件 IP查询" src="http://www.byvoid.com/blog/wp-content/uploads/2008/11/cogs_ipquery.png" alt="" width="640" height="600" /></a></p>
<h3  class="related_post_title">Maybe you like</h3><ul class="related_post"><li><a href="http://www.byvoid.com/blog/change-to-dreamhost/" title="换用Dreamhost">换用Dreamhost</a></li><li><a href="http://www.byvoid.com/blog/ubuntu-week-note/" title="Ubuntu 一周小记">Ubuntu 一周小记</a></li><li><a href="http://www.byvoid.com/blog/browser-kernel/" title="几种浏览器的内核">几种浏览器的内核</a></li><li><a href="http://www.byvoid.com/blog/vakuum-dev-note-01/" title="Vakuum开发笔记01 开天辟地">Vakuum开发笔记01 开天辟地</a></li><li><a href="http://www.byvoid.com/blog/break-firefox/" title="破解Firefox密码管理器加密的信息">破解Firefox密码管理器加密的信息</a></li><li><a href="http://www.byvoid.com/blog/cogs-queue/" title="COGS 评测排队问题">COGS 评测排队问题</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.byvoid.com/blog/firefox-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>COGS 评测排队问题</title>
		<link>http://www.byvoid.com/blog/cogs-queue/</link>
		<comments>http://www.byvoid.com/blog/cogs-queue/#comments</comments>
		<pubDate>Sat, 19 Jul 2008 07:16:31 +0000</pubDate>
		<dc:creator>BYVoid</dc:creator>
				<category><![CDATA[設計開發]]></category>
		<category><![CDATA[COGS]]></category>
		<category><![CDATA[排队]]></category>
		<category><![CDATA[效果图]]></category>
		<category><![CDATA[评测]]></category>

		<guid isPermaLink="false">http://www.byvoid.com/blog/?p=200</guid>
		<description><![CDATA[其实在做COGS之前，看到许多评测系统Pending&#8230;Waiting&#8230;..Running&#8230;..Accept这种格式，尤其是以 Vijos和pku为代表，交了题还看不到结果，要在Status不断刷新等待。我对这种模式十分反感，更喜... ]]></description>
			<content:encoded><![CDATA[<p>其实在做COGS之前，看到许多评测系统Pending&#8230;Waiting&#8230;..Running&#8230;..Accept这种格式，尤其是以 Vijos和pku为代表，交了题还看不到结果，要在Status不断刷新等待。我对这种模式十分反感，更喜欢USACO人性化的方式，所以COGS开发初期是完全以USACO为蓝本做的，从文件提交方式可以看出来。<br />
最初做的时候没有考虑排队，也就是开启多个线程，来多少评测多少，没有考虑共享CPU造成卡时不准问题。后来考虑到了，就给评测机加上了锁定功能，也引发了死锁问题。上个版本修正了死锁问题，但当OIER大量提交的时候会经常出现“当前没有空闲的评测机”的问题。有人要求加上Waiting队列，但我实在不想模仿Vijos，就自己想了一个解决方案。</p>
<p>实现评测和队列，评测页面、比赛评测页面、提交列表页面用Javascript重写，动态排队。全部由Ajax实现，无需刷新。</p>
<p>评测页面效果图<br />
图1<br />
<img src="http://www.byvoid.com/ima/cojs_compile_imagine/cojs_compile_imagine_01.GIF" alt="" /><br />
图2<br />
<img src="http://www.byvoid.com/ima/cojs_compile_imagine/cojs_compile_imagine_02.GIF" alt="" /><br />
图3<br />
<img src="http://www.byvoid.com/ima/cojs_compile_imagine/cojs_compile_imagine_03.GIF" alt="" /><br />
图4<br />
<img src="http://www.byvoid.com/ima/cojs_compile_imagine/cojs_compile_imagine_04.GIF" alt="" /></p>
<h3  class="related_post_title">Maybe you like</h3><ul class="related_post"><li><a href="http://www.byvoid.com/blog/vakuum-dev-note-01/" title="Vakuum开发笔记01 开天辟地">Vakuum开发笔记01 开天辟地</a></li><li><a href="http://www.byvoid.com/blog/vakuum-oj-dev/" title="开源的在线评测系统——Vakuum">开源的在线评测系统——Vakuum</a></li><li><a href="http://www.byvoid.com/blog/firefox-js/" title="还是Firefox执行脚本快">还是Firefox执行脚本快</a></li><li><a href="http://www.byvoid.com/blog/cogs-v002/" title="COGS V0.02">COGS V0.02</a></li><li><a href="http://www.byvoid.com/blog/ooj-setup/" title="OOJ配置记">OOJ配置记</a></li><li><a href="http://www.byvoid.com/blog/cogs-plan/" title="在线评测系统发布计划">在线评测系统发布计划</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.byvoid.com/blog/cogs-queue/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>COGS V0.02</title>
		<link>http://www.byvoid.com/blog/cogs-v002/</link>
		<comments>http://www.byvoid.com/blog/cogs-v002/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 06:20:27 +0000</pubDate>
		<dc:creator>BYVoid</dc:creator>
				<category><![CDATA[設計開發]]></category>
		<category><![CDATA[COGS]]></category>
		<category><![CDATA[更新]]></category>
		<category><![CDATA[版本]]></category>

		<guid isPermaLink="false">http://www.byvoid.com/blog/?p=194</guid>
		<description><![CDATA[更新说明 *不可提交对管理员无效 *增强提交记录 记录IP，保留每次提交的代码 *增加按运行时间排名 *把进入题库、比赛、分类放到上边栏 *合并前台与后台(题目列表，分类列表，用户列表，用... ]]></description>
			<content:encoded><![CDATA[<p>更新说明</p>
<p>*不可提交对管理员无效<br />
*增强提交记录 记录IP，保留每次提交的代码<br />
*增加按运行时间排名<br />
*把进入题库、比赛、分类放到上边栏<br />
*合并前台与后台(题目列表，分类列表，用户列表，用户组列表，提交记录，评测机)，开放某些页面<br />
*页增加匿名阅读权限，方便搜索引擎抓取<br />
*用户更改即时生效问题<br />
*初步解决评测机锁死问题</p>
<h3  class="related_post_title">Maybe you like</h3><ul class="related_post"><li><a href="http://www.byvoid.com/blog/dvcs-mercurial/" title="分布式版本控制系统——Mercurial">分布式版本控制系统——Mercurial</a></li><li><a href="http://www.byvoid.com/blog/vakuum-dev-note-01/" title="Vakuum开发笔记01 开天辟地">Vakuum开发笔记01 开天辟地</a></li><li><a href="http://www.byvoid.com/blog/firefox-js/" title="还是Firefox执行脚本快">还是Firefox执行脚本快</a></li><li><a href="http://www.byvoid.com/blog/cogs-queue/" title="COGS 评测排队问题">COGS 评测排队问题</a></li><li><a href="http://www.byvoid.com/blog/ooj-setup/" title="OOJ配置记">OOJ配置记</a></li><li><a href="http://www.byvoid.com/blog/cogs-plan/" title="在线评测系统发布计划">在线评测系统发布计划</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.byvoid.com/blog/cogs-v002/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
