byers さんのプロフィール安全第一-长风野老,铁臂山人フォトブログリスト ツール ヘルプ

安全第一-长风野老,铁臂山人

roger byers

職業
所在地
好きなもの/好きなこと
全世界无产者联合起来!
全 17 枚中 1 枚目

YOBO

 
lonegunman一起在友播听歌吧!
12月3日

CSLA.NET的对象属性写权限验证与我的对象属性写权限验证对比

public static readonly PropertyInfo<string> DataProperty = RegisterProperty(
      typeof(Blah),
      new PropertyInfo<string>("Data"));
   
    public string Data
    {
      get { return GetProperty(DataProperty); }
      set { SetProperty(DataProperty, value); }
    }
    protected override void AddBusinessRules()
    {
      ValidationRules.AddRule(DoAsyncRule, DataProperty);
    }
    private static void DoAsyncRule(AsyncValidationRuleContext context)
    {
      BackgroundWorker worker = new BackgroundWorker();
      worker.DoWork += (o, e) => Thread.Sleep(3000);
      worker.RunWorkerCompleted += (o, e) =>
      {
        string val = (string)context.PropertyValues["Data"];
        if (val == "Error")
        {
          context.OutArgs.Result = false;
          context.OutArgs.Severity = RuleSeverity.Error;
          context.OutArgs.Description = "Invalid data!";
        }
        else if (val == "Warning")
        {
          context.OutArgs.Result = false;
          context.OutArgs.Severity = RuleSeverity.Warning;
          context.OutArgs.Description = "This might not be a great idea!";
        }
        else if (val == "Information")
        {
          context.OutArgs.Result = false;
          context.OutArgs.Severity = RuleSeverity.Information;
          context.OutArgs.Description = "Just an FYI!";
        }
        context.Complete();
      };
      worker.RunWorkerAsync();
    }
  }
以上是CSLA.NET中如何对对象的某一个属性的写操作进行权限验证的。以下代码是我的框架中对对象属性写操作以及方法调用的权限验证代码:
class Program
    {
        static void Main(string[] args)
        {
            User user = new User("zjhe", "password");
            SecurityServiceFacade.AuthenticateUser(user);
            IA a = PolicyInjection.Create<A, IA>();
            a.Print("S");
        }
    }
    public interface IA
    {
        [Rule("PrintRule")]
        void Print(string s);
    }
    public class A : IA
    {
        public virtual void Print(string s)
        {
            Console.WriteLine("A");
        }
    }
 
从代码实现上来看我的代码简单一些,但是要用到面向方面中动态类型生成,在性能上是有损失的,希望可以在运行时通过Emit把代理类对象生成的开销降下来。我认为对于最终程序员来说我的控制方式免编码(除了用特性标注某个方法对应怎样的权限),不易出错,比起CSLA.NET中要通过属性名来得到属性值更占优势。但是CSLA.NET中的这个Context一直是我希望借鉴的设计,我希望也能在我的框架中充实一个安全上下文环境。
我最近决定从CSLA.NET提供的Sample来学习借鉴这个优秀的.NET企业开发框架,借鉴它设计中闪光的优点为我所用。
去年到今年一共写了三个框架,权限验证框架、数据访问框架以及内存-数据库表缓存同步框架,我正在努力地将它们融合到一起,重写其中许多代码,学习借鉴优秀项目中相关部分的优秀经验。对企业应用框架又有了一些新的理解。
11月27日

还是IndexOUtOfRangeException

2009.12.03,今天还是看到了错误,以下代码并不能解决问题,我问了微软的MattN,他正在与Enterprise Library的开发人员一道思考如何解决。

我现在怀疑出问题的代码不在ExecuteReader,而是在ExecuteScalar里。

 

"SQLDataReader.GetOrdinal() fails rarely with IndexOutOfRange"

这个问题困扰了我们很久,虽然通过切分数据库连接池可以在一定的程度上缓解这种现象的发生,但还是偶尔会发生。幸好帖子后面微软的一个大牛Matt N给了一些回复,并且他直接与Enterprise Library组的人进行了沟通。我发现最新的Enterprise Library 5.0的代码中已经有了相应的变化:

public virtual IDataReader ExecuteReader(DbCommand command)
  {
            //ConnectionWrapper wrapper = GetOpenConnection(false);

            //try
            //{
            //    //
            //    // JS-L: I moved the PrepareCommand inside the try because it can fail.
            //    //
            //    PrepareCommand(command, wrapper.Connection);

            //    //
            //    // If there is a current transaction, we'll be using a shared connection, so we don't
            //    // want to close the connection when we're done with the reader.
            //    //
            //    if (Transaction.Current != null)
            //        return DoExecuteReader(command, CommandBehavior.Default);
            //    else
            //        return DoExecuteReader(command, CommandBehavior.CloseConnection);
            //}
            //catch
            //{
            //    wrapper.Connection.Close();
            //    throw;
            //}

            DbConnection connection = null;
            CommandBehavior commandBehavior;

            if (Transaction.Current == null)
            {
                commandBehavior = CommandBehavior.CloseConnection;
                connection = this.GetNewOpenConnection();
            }
            else
            {
                // If there is a current transaction, we'll be using a shared connection, so we don't
                // want to close the connection when we're done with the reader.
                commandBehavior = CommandBehavior.Default;
                connection = TransactionScopeConnections.GetConnection(this);
            }

            try
            {
                PrepareCommand(command, connection);
                return DoExecuteReader(command, commandBehavior);
            }
            catch
            {
                if (commandBehavior == CommandBehavior.CloseConnection)
                {
                    // close only if the connection if not shared.
                    // the connection is closed by SqlCommand in the ocurrence of an exception if the CommandBehavior is
                    // CloseConnection, but this is not documented so the connection will be closed explicitly unless
                    // it is shared.
                    connection.Close();
                }
                throw;
            }

  }

原来代码的问题是,如果代码中有事务中的多个查询出现,就是说先有一个DataReader的情况下,又启动了一个DataReader查询另一个结果集,第二个结果集查询时出了异常时,会直接调用connection.Close,这个connection是两个DataReader共享的。这个连接会被释放,放回连接池,但是这个事务还没有结束!与一个有别的查询的事务还有关系的连接被放回连接池,然后又被另一个线程另一个事务复用进行查询,会产生何种后果?以下是反出来的SqlConnection的Close方法:

public override void Close()
{
    IntPtr ptr;
    Bid.ScopeEnter(out ptr, "<sc.SqlConnection.Close|API> %d#", this.ObjectID);
    try
    {
        SqlStatistics statistics = null;
        SNIHandle target = null;
        RuntimeHelpers.PrepareConstrainedRegions();
        try
        {
            target = SqlInternalConnection.GetBestEffortCleanupTarget(this);
            statistics = SqlStatistics.StartTimer(this.Statistics);
            lock (this.InnerConnection)
            {
                this.InnerConnection.CloseConnection(this, this.ConnectionFactory);
            }
            if (this.Statistics != null)
            {
                ADP.TimerCurrent(out this._statistics._closeTimestamp);
            }
        }
        catch (OutOfMemoryException exception3)
        {
            this.Abort(exception3);
            throw;
        }
        catch (StackOverflowException exception2)
        {
            this.Abort(exception2);
            throw;
        }
        catch (ThreadAbortException exception)
        {
            this.Abort(exception);
            SqlInternalConnection.BestEffortCleanup(target);
            throw;
        }
        finally
        {
            SqlStatistics.StopTimer(statistics);
        }
    }
    finally
    {
        SqlDebugContext context = this._sdc;
        this._sdc = null;
        Bid.ScopeLeave(ref ptr);
        if (context != null)
        {
            context.Dispose();
        }
    }
}

 

internal virtual void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
{
    Bid.PoolerTrace("<prov.DbConnectionInternal.CloseConnection|RES|CPOOL> %d# Closing.\n", this.ObjectID);
    if (connectionFactory.SetInnerConnectionFrom(owningObject, DbConnectionOpenBusy.SingletonInstance, this))
    {
        try
        {
            DbConnectionPool pool = this.Pool;
            Transaction enlistedTransaction = this.EnlistedTransaction;
            if ((null != enlistedTransaction) && (enlistedTransaction.TransactionInformation.Status != TransactionStatus.Active))
            {
                this.DetachTransaction(enlistedTransaction);
            }
            if (pool != null)
            {
                pool.PutObject(this, owningObject);
            }
            else
            {
                this.Deactivate();
                this.PerformanceCounters.HardDisconnectsPerSecond.Increment();
                this._owningObject.Target = null;
                if (this.IsTransactionRoot)
                {
                    this.SetInStasis();
                }
                else
                {
                    this.PerformanceCounters.NumberOfNonPooledConnections.Decrement();
                    if (base.GetType() != typeof(SqlInternalConnectionSmi))
                    {
                        this.Dispose();
                    }
                }
            }
        }
        finally
        {
            connectionFactory.SetInnerConnectionEvent(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
        }
    }
}

可以看到,在启用连接池的情况下,这个连接直接被放回了连接池。可能我水平太低,没有直接看到什么地方是把连在这个连接上的Reader释放掉的地方。
新的修改的作用是,在启用事务的情况下,只有在没有事务的情况下Reader的异常会关闭连接,否则连接必须由事务来进行关闭。
我修改了我们的Enterprise Library 3.1的代码,准备观察一段时间,希望可以解决这个问题。
11月23日

如何制作合格的燃烧弹,以及等等

最近闵行有户人家公然对抗天朝强拆队,动用了莫洛托夫瓶。但是从照片看就知道他们是业余水平的选手。。。消防队的水枪迅速地消灭了燃烧弹。他们肯定是没有读过《如何制作莫洛托夫燃烧瓶》,这绝对是一件技术活,不是拍脑袋想干就能干得好的事情。本着科学探索的精神,我研究了一下,准备以后上下班身带燃烧弹,外加大号大力钳,以及4台dv摄像机。大力钳用来防钓钩,有人拔钥匙我就买有无钥匙点火功能的车,他踩刹车我就用大力钳剪断钓钩;dv摄像机是如果看到有人倒在路边,特别是老年人倒在地上起不来,首先用四台dv摄像机来一个360度环绕拍摄,然后让老人对每一台dv机高喊“是我自己摔倒的”,然后收好dv机和录像带找信得过的人送往安全地方保存以后再去给予必要的帮助。。。燃烧弹是用来回家时如果发现有人要拆我们家的房子我也不问他们是谁了,反正是zf的人;我也不要他们出示法律文件了,反正他们手写的白条也能作数的;我就寄希望于燃烧弹、反坦克桩、隆美尔尖桩、粑粑雷等非对称武器自己维权了。其实对抗强拆这种事情是一个很细腻很复杂的技术工程。燃烧弹是用来进攻的,作为防守手段我们需要在墙上门上贴满写满天朝万岁,陛下万岁的口号标语,挂满宝宝涛涛的大幅照片(我记得明朝靖难时候也有人这么对付朱棣的),然后出于党性的召唤提醒强拆队员们小心别在执行公务中破坏河蟹社会了。。。最后如果攻守皆不能成功你只能双手抱头高喊三声“我听话”,然后放弃抵抗了。。。
建议强拆队也借鉴郑州城管的经验:
有人说加了93号以后车子点火有困难,空滤积炭增多,这纯粹是胡说八道诬蔑我朝。我朝只是在93号燃油中增加了一些燃油添加剂,每百升添加20升即可达到油耗减少六分之一的效果,这种技术活说了那些造谣的人也不懂的,这是高科技技术活,八星八箭省油精。
最近从胖子那里买了件不错的wolfskin的冲锋衣,以后出去玩就可以风雨无阻了,呵呵。
11月15日

红白事

人的一生无非是红白事之间的那个过程,大部分都是从某俩人结婚开始,然后生子,一个人就来到了世界上。这个人自己也会去结婚,也会去生子,到最后终究是要走向死亡。本周发生了两件事情,第一,我的好朋友,我的同事plu结婚了,今天星期天,去参加了他的婚礼;第二,我的祖父,在一个阴冷的星期六的下午,在康复医院的一间病房里,突然就呼吸衰竭,走了。

当然这两件事没有任何直接的或者间接的联系。plu结婚,我感到高兴;祖父逝世,我感到伤心。然而两件事情前后脚发生,实在是让我觉得有些突兀。上两辈人的事情,本来我就兴趣不大,只是从小就从父亲的口中听到一个暴君的祖父的形象,专横、冷酷,伴随着父权的威严。父亲兄弟四人与祖父的关系都不是太好,所以与祖父也不经常来往。祖父一次在老家绍兴突然犯病,父亲去探望时发现祖父的神志已经不如往日清晰,于是兄弟四人一商议,把祖父从老家接到了上海的一家康复医院。

康复医院、敬老所养老院我去过,说实话从心眼里就讨厌那种地方,主要是讨厌那里的气氛。一群迈入暮年的老人,多半都是行动不便、神志不清的老人在那里或卧或坐,你走到那里就有一种非常非常压抑的感觉。曹操写,烈士暮年,壮心不已,在那里你是看不到这样的意境的。我的祖母虔信佛教,每天早睡早起,念经礼佛,功课一日不曾歇息,身体倒还不错,神志也是十分清楚。我想除了佛祖保佑以外,每天念经礼佛对大脑也有很好的作用,另外人在精神上也有一个寄托,不至于活的不知所谓。

结婚是一个人拥抱另一个人的世界,死亡是一个人彻底回归宇宙消除自我独立存在的状态。这两件事有一个共同点,就是人们都会不停地问自己,我到那时身边有谁,是什么样的一个状况。我最近就在想,我会和一个什么样的人结婚,共同生活,又会以什么样的方式死去。

巴顿将军里面有一句台词,一个将军最好的归宿就是,在最后一场战役中被最后一颗子弹击中死去。好比吃甘蔗一样,人生应该有它甜美的部分;人的一生十分短暂,应该抓住时机轰轰烈烈地做一些什么,用这样或者那样的方式向世界宣告,我存在过。在经历了一场又一场辉煌的战役后,一个极负尊严的人,又怎么能够接受命运在剩下的漫长岁月里给他安排的漫漫褪色的判决呢?

与其黯然逝去,不如灿烂涅磐。我是一个比较理想主义的人,不接受与理想方向不同的选择,经常会像赌徒一样选择比较另类的路线;我希望我是倒在追求问题与答案的道路上的,而不是在对一切都无所谓了以后,在风中,在一个阴冷的下午,骨瘦如柴地躺在一张床上,在陌生的护工面前黯然逝去。

plu今天很给面子,我们灌了他还算不少的酒;也见识到了沛嫂是个能喝的女人。由衷地为沛哥与沛嫂的结合感到高兴,并且为他们祝福。

另外,最近很没有心情,所以很久没有想写一些什么的冲动了。其实最近还是有一些事情的,比如国庆后想好去西藏玩,可是到那里高原反应比较重,一算等反应减弱了领导批的假期也没了,所以转到成都玩了几天;比如11月跑到流感肆虐的北京参加了微软的tech .ed 2009,看到了一些东西。但是人呢是越来越懒惰,懒得整理一些东西和感想出来。我现在就像一只躲在壳里头的乌龟,只希望能够早日熬出头,也算有个盼头。现在的工作,除了同事们人品都还不错以外,职业发展前景、薪资等我都是很不满意的;唯一支撑我到现在的也就是传说中领导手里的大杀器了,可是到现在也没有一个准信。希望这真的只是黎明前最后的黑暗了,早点给我一个信号吧,是去是留,就看明年了。

还是那句话,走寻常路只能获得寻常结果,与其黯然逝去不如灿烂涅磐,我就再赌上它一年吧。

9月15日

计算中的世界与全球意识体

一花一世界,一树一菩提。数学是宇宙的抽象,数学中存在着无穷大与无穷小,事实上无穷大和无穷小都是世界的本质的一部分,同时无穷复杂也是世界本质的一部分。如同你将现实中存在的任意一条直线无限地放大放大再放大,它一定会变得扭扭歪歪;任意一张桌子的表面积都可以是无穷大,只要你观察的工具可以无限地把平面上的凹凸放大。真实存在的复杂性可以很轻松地超越人类一切计算能力的总和,任意真实存在的系统在无穷精化后都将复杂的不可计算(只要到量子级别就不可测量了,更不用提计算)。
然而如同几十亿年前地球的某个地方出现了某种大分子结构的有机物一样到复杂的万物生灵,由世界孕育演化出的生命体演化出了智能,慢慢地发展到现在由我们人类设计并且制造出了专门用于计算的设备,计算也经历了从无到有的演进。从我们开始对周围的世界进行思考开始,地球上的计算密度就开始缓步提升。如果我们定义一种单位,以一个现代人的单位时间计算能力为基础单位,那么每平方公里的计算密度是呈指数级别增长的,特别是计算机的出现是这个增长的拐点。我们制造了各种各样的机器,将人类从拉犁收割、步行划船等体力活动中解放出来,还建造了计算机将人类从低级计算中解放了出来。
目前的社会,计算已经融入了方方面面。没有计算,飞机将会坠毁,交通会瘫痪,金融系统会被彻底摧毁,所有的经济体都将土崩瓦解。互联网的出现使得交流变得廉价,广义上的协同思考已经像电力自来水一样是社会对我们提供的基础性服务;人和人可以更加轻松地交流思想,知识可以传播地更快。个人受他人的影响越来越大,像尼采那样孤立封闭的超级哲人很难继续存在下去。
在可预见的未来,计算密度将会越来越高,我们会建立越来越精密的系统,模拟真实社会;会有越来越高效的嵌入式设备投入使用,他们必然会越来越多地是互联网的延伸设备;计算与信息会变得像空气一样,免费、唾手可得,但是又是性命攸关的。在这种情况下,组织与组织的界限更多的会变成他们后台系统、群体之间的界限,会有更多的融合意识出现。在法律上我们将企业视作一个有人类权利的虚拟人,称之为法人;在将来,我们将会把通过网络产生的群体意识、集体意识看作一个有独立思维能力的人;这个人的意识由组成它的无数真实的人的意识混合产生,反过来又会影响到这些组成它的人。艾泽拉斯大陆对于非魔兽世界玩家来说是什么?对于骨灰级魔兽世界玩家来说又是什么?我们可以这样来看,把全体魔兽世界玩家的混合意识看作是一个人,那么任何对魔兽世界这个游戏的致命威胁都是对这个人的致命威胁,必然引起它的反感与抗争。当然目前个体意识和群体意识的关联还没有达到为了个体意识为了群体意识产生的求生意识去不择手段的地步,但是越来越多的群体意识的利益与个体意识的利益挂钩。发展到最后,我幻想会出现一个具有自我意识,可以自主选择发展方向的全球性意识体,它是由全球无数多的个体意识在一起组成的。
在未来这样的全球意识体发展成熟以后,个体意识将变得更加无从轻重,个体的意识在群体意识面前就像一只瑟瑟发抖的被拔光毛的鸡,除了战战兢兢地四处寻找庇护所它别无他法,更别提去抵抗这种群体意识了。最后,独立的思想会越来越少,人类合为一体。
9月9日

秋夜

昨日通宵,今日睡到日晒三竿才起来;下午闲来无事,洗了个澡就跑去公司逛逛,出门时一阵微风拂过,加上今日灿烂的阳光明亮却不烤人,甚是舒心;加上最为艰苦地工作已随昨夜而逝,油然有一种身无所依,心无所系,悠悠然游离于世外的幻觉。待得晚饭后,走在路上,感觉手脚发热,竟是越走越轻松,越走越畅快。回到家里,坐在桌前,打开窗子,鬼使神差地找到肖邦的降E大调夜曲播放,流水一般的旋律滑出音箱,配合窗外传来的阵阵虫鸣,竟是如此地和谐美妙,只觉有一股清泉缓缓流过心田,顿时工作的压力、焦躁、烦恼都不见了,精神也是为之一振。难道今天宇宙射线的频率与我的小宇宙很合拍?万籁俱寂之中居然有一些天人合一的感应。。。
我最近太过焦躁,现在夜深人静一个人反思,真是觉得没有必要。可能是我太渴望成功,太渴望挑战,忘记了这路上的磕磕绊绊琐碎杂事也是必须经历的,就像牛顿经典力学中设想的没有摩擦力的理想表面现实中是不存在的一样,不该如此地急躁。
让一切烦恼随着旋律流走吧,至少在晚上,是我自己的时间,我应该忘记烦恼,做一些喜欢的事情。
9月7日

最近

最近内火很大,比较急躁。
很多的事情都步入了一个最后的阶段,辛苦了一年的系统积攒了一年多的问题也正在一个一个爆发再扑灭,推广工作也已经进入了尾声,只剩下最后一批门店了。回想起和同事们一夜一夜地努力,看着这个长得很畸形的系统还是顽强地站立起来支撑起那么多的业务,还是很有感触的。读书也快要结束了,这些天在赶论文,写的就是这个做了一年的系统,赶着赶着发现自己原来的实现有许许多多丑陋的地方,还要回过头去修补。等待了一年多的事情也有了一个比较乐观的未来,虽然还不知道未来会是怎么样,但总是一颗定心丸,眼看自己一直想做的事情终于从不可能变成了可能。未来,好像离我只有一年的距离。
我想最近急躁,可能就是这么许多事情都处于一个要出结果还没出的状态,好比XX前的疼痛,以及期待一般。
很庆幸自己依然愤怒,依然不愿妥协,依然桀骜,虽然无数过来人对我说,做人要XXXX(省略一万字)。但是我仍然相信,天地是广阔的,人性是美好的,人是要做大事的,妥协是不可接受的。如果人不能像利剑一样锋芒毕露,那也要做到像玄铁剑那样重剑无锋大巧不工。男儿立于人生天地间,当提三尺剑立不世之功。忍耐,继续忍耐下去,虽然有可能到最后还是一场空,但毕竟我有过一个梦想,我离它是那么的近。
加油!!!
9月1日

我怎么了?

最近不是一般的愤怒,愤怒愤怒愤怒,对周边一切事物都感到厌烦与愤怒,我想要咆哮咆哮再咆哮。。。
为什么总是有那么多烦心的事情?如果人人做事时都为别人考虑一点,都想到自己的举动会对别人造成什么样的影响,哪里会有那么多横生出来的事情?
8月7日

老狗学不会新把戏

都说老狗学不会新把戏,为了不沦为老狗,我还是要保持不停地学习。
最近在学习scala语言,一种面向对象的函数式语言,目前运行于jvm之上,可以与java互操作。
官方提供了一个很不错的站点提供培训:http://www.simplyscala.com/
为什么我决定学习一下这个语言呢?主要是以前很惭愧没有学习过函数式语言,正好就拿这个入门了。函数式的好处很多,例如下面的样例代码
 
abstract class TreeN
case class InterN(key:String,left:TreeN,right:TreeN) extends TreeN
case class LeafN(key:String,value:Int) extends TreeN

def find(t:TreeN,key:String):Int={
     t match {
         case InterN(k,l,r) => find((if(k>=key)l else r),key)
         case LeafN(k,v) => if(k==key) v else 0
    }
}
// create a binary tree
val t=InterN("b",InterN("a",LeafN("a",1),LeafN("b",2)),LeafN("c",3))
/*       [b]
         / \
       [a] c,3
       / \
     a,1 b,2
*/
 
寥寥几行定义了一个二叉搜索树。核心的地方在于find函数这里,完全体现了函数式在这方面相较于命令式语言的优越性,就是在写递归的时候非常简洁。其他的我还是刚刚学习,还需要好好体会。