小编Val*_*nck的帖子

我可以使用http-kit和core.async创建一个完全无阻塞的后端应用程序吗?

我想知道是否可以使用http-kit整合一个完全无阻塞的Clojure后端Web应用程序.

(实际上任何与Ring兼容的http服务器都没关系;我提到了http-kit,因为它声称有一个事件驱动的非阻塞模型).


编辑:TL; DR

这个问题是我对非阻塞/异步/事件驱动系统性质的一些误解的症状.如果你和我在同一个地方,这里有一些澄清.

只有当所有(例如,大多数)IO从头开始以非阻塞方式处理时,才能使事件驱动系统具有非阻塞的性能优势(如在Node.js中).这意味着所有数据库驱动程序,HTTP服务器和客户端,Web服务等都必须首先提供异步接口.特别是:

  • 如果您的数据库驱动程序提供同步接口,则无法使其成为非阻塞.(您的线程被阻止,无法检索它).如果你想要非阻塞,你需要使用其他东西.
  • 像core.async这样的高级协调实用程序无法使系统无阻塞.它们可以帮助您管理非阻塞代码,但不启用它.
  • 如果您的IO驱动程序是同步的,您可以使用core.async来获得异步的设计优势,但是您将无法获得它的性能优势.您的线程仍将浪费时间等待每个响应.

现在,具体来说:

  • 作为HTTP服务器的http-kit提供了非阻塞的异步接口.见下文.
  • 但是,许多Ring中间件由于它们基本上是同步的,因此与这种方法不兼容.基本上,任何更新返回响应的Ring中间件都不可用.

如果我做对了(我不是专家,所以请告诉我,如果我正在做错误的假设),Web应用程序的这种非阻塞模型的原则如下:

  1. 有一些超快的OS线程处理所有CPU密集型计算; 这些绝对不能等待.
  2. 有很多"弱线程"处理IO(数据库调用,Web服务调用,休眠等); 这些主要是为了等待.
  3. 这是有益的,因为在处理请求上花费的等待时间通常是2(磁盘访问)到5(Web服务调用)数量级高于计算时间.

从我所看到的,默认情况下,Play Framework(Scala)和Node.js(JavaScript)平台支持此模型,具有基于承诺的实用程序,用于以编程方式管理异步.

让我们尝试使用Compojure路由在基于Ring的clojure应用程序中执行此操作.我有一个通过调用my-handle函数构造响应的路由:

(defroutes my-routes
  (GET "/my/url" req (my-handle req))
  )
(def my-app (noir.util.middleware/app-handler [my-routes]))
(defn start-my-server! [] 
  (http-kit/run-server my-app))
Run Code Online (Sandbox Code Playgroud)

在Clojure应用程序中管理异步的普遍接受的方式似乎是基于CSP,使用core.async库,我完全没问题.因此,如果我想接受上面列出的非阻塞原则,我将以my-handle这种方式实现:

(require '[clojure.core.async :as a])

(defn my-handle [req]
  (a/<!!
    (a/go ; `go` makes channels calls asynchronous, so I'm not …
Run Code Online (Sandbox Code Playgroud)

clojure nonblocking ring core.async http-kit

35
推荐指数
1
解决办法
4832
查看次数

从(AngularJS)单页面应用程序直接(简单!)AJAX上传到AWS S3

我知道上传到AWS S3有很多报道.但是,我一直在努力解决这个问题大约24小时,我没有找到适合我情况的任何答案.

我想做什么

将文件直接从我的客户端上传到AWS S3到我的S3存储桶.情况是:

  1. 它是单页应用程序,因此上传请求必须在AJAX中
  2. 我的服务器和我的客户端不在同一个域中
  3. S3存储桶是最新的(法兰克福),一些签名生成库不起作用(见下文)
  4. 客户在AngularJS
  5. 服务器在ExpressJS中

我试过的

  • Heroku关于直接上传到S3 的文章.不适合我的客户端/服务器配置(加上它真的不适合Angular)
  • 现成的指令,如ng-s3upload.不起作用,因为最近的s3存储桶不接受它们的签名生成算法.
  • 在本文中手动创建文件上载指令和逻辑,如本文所述(使用FormData和Angular $http).它包括从服务器上的AWS获取签名的URL(并且该部分工作),然后AJAX上传到该URL.它失败了一些神秘的CORS相关消息(虽然我确实在Heroku上设置了CORS配置)

我似乎面临两个困难:在我的单页应用程序中使用文件输入,并使AWS的工作流程正确.

我正在寻找的那种解决方案

如果可能的话,我想避免"全部包含"的解决方案来管理整个过程,同时隐藏所有的复杂性,使其难以适应特殊情况.我宁愿有一个简单的解释来分解所涉及的各个组件之间的数据流,即使它需要我更多的管道.

ajax file-upload amazon-s3 singlepage angularjs

15
推荐指数
1
解决办法
6460
查看次数

在Clojure应用程序中声明Datomic架构的推荐方法

我开始开发一个由Datomic支持的Clojure应用程序,我想知道什么是声明架构的最佳方式,以解决以下问题:

  1. 具有简洁,可读的模式表示
  2. 在运行我的应用程序的新版本之前,确保架构已安装并且是最新的.

直觉上,我的方法如下:

  1. 声明一些辅助函数使模式声明比原始映射更简洁
  2. 作为应用程序初始化的一部分自动安装架构(我还不知道是否总是有效).

这是最好的方式吗?人们通常如何做到这一点?

schema clojure datomic

9
推荐指数
1
解决办法
1799
查看次数

Datomic:与"重置"操作的多对多关系的模式

我正在寻找关于在Datomic中建模某些多对关系的方法的反馈.

问题

假设我想为一个人有一个最喜欢的电影列表的域设计Datomic模式.举例来说,John最喜欢的电影是Gladiator,Star WarsFight Club.

在Datomic中对此进行建模的最明显的架构是具有基数多属性,例如:

#{["John" :person/favorite-movies "Gladiator"]
  ["John" :person/favorite-movies "Star Wars"]
  ["John" :person/favorite-movies "Fight Club"]}
Run Code Online (Sandbox Code Playgroud)

这种方法可以很容易地从列表中添加或删除电影(简单地使用:db/add:db/retract),但我发现重置整个电影列表是不切实际的- 你基本上需要计算旧列表和新列表之间的差异,并且在事务函数中运行.当列表的元素不是标量时,这会变得更糟.

替代方法

作为替代方法,我正在考虑使用set实体引入间接:

#{["John" :person/favorite-movies 42]
  [42 :set.string/contains "Gladiator"]
  [42 :set.string/contains "Star Wars"]
  [42 :set.string/contains "Fight Club"]}
Run Code Online (Sandbox Code Playgroud)

使用这种方法,:person/favorite-movies是一个基数 - 一,ref-typed属性,并且:set.string/contains是基数多,字符串类型的属性.然后重置列表只需创建一个新的集合实体:

[{:db/id "John"
  :person/favorite-movies {:db/id (d/tempid :db.part/user)
                           :set.string/contains ["Gladiator" 
                                                 "The Lord of the Rings"
                                                 "A Clockwork Orange"
                                                 "True Romance"]}}]
Run Code Online (Sandbox Code Playgroud)

这种建模到多种关系的方法是否存在已知的局限性?


编辑:一个不太重要的用例 …

database-design datomic

7
推荐指数
1
解决办法
436
查看次数

我如何以编程方式访问当前的webdriver实例?

我正在使用Protractor编写一个e2e测试套件.

我知道它建立在WebdriverJS之上,我正在尝试使用一些webdriverJS功能.

也就是说,我正在尝试使用webdriverJS的promise管理器排队某些行为,而WebdriverJS文档说我应该使用

webdriver.promise.controlFlow().execute(function myBehavior(){...});
Run Code Online (Sandbox Code Playgroud)

麻烦的是,我不知道如何访问该"webdriver"对象.没有名为"webdriver"的全局变量.

有人可以帮我吗?

编辑:

既然问题已经解决了,我想强调一个必须使用的事实

browser.driver.controlFlow()
Run Code Online (Sandbox Code Playgroud)

并不是

browser.driver.promise.controlFlow()
Run Code Online (Sandbox Code Playgroud)

尽管WebdriverJS文档可能会提出建议.

javascript selenium-webdriver protractor

6
推荐指数
1
解决办法
3313
查看次数

let forms:如何访问宏中的结构化符号?

我正在尝试编写一个宏,它通过解构扩展为let形式.我的问题是我希望得到let表单中定义的符号列表,包括通过destruturing获得的符号.

用例

我试图将这种行为分解出来,例如验证:

(let [a (foo bar)
      {x :x,
       y :y,
       {u :u, v: v :as nested-map} :nested} some-map]
  (and x y nested-map u v ; testing truthiness
       (valid-a? a)
       (valid-x? x)
       (valid-y? y)
       (valid-nested? nested-map)
       (valid-u-and-v? u v)
       ))
Run Code Online (Sandbox Code Playgroud)

提出的解决方案

通过某种类型的and-let宏来实现这一点真的很好,我可以像这样调用它:

(and-let [a (foo bar)
          {x :x,
           y :y,
           {u :u, v: v :as nested-map} :nested} some-map]
         (valid-a? a)
         (valid-x? x)
         (valid-nested? nested-map)
         (valid-u-and-v? u v))
Run Code Online (Sandbox Code Playgroud)

我错过了什么

但是我错过了一些访问let表单中绑定的符号列表的方法.如果我有类似list-bound-symbols函数的东西,我可以这样做:

(defmacro and-let
  "Expands to an AND close …
Run Code Online (Sandbox Code Playgroud)

macros clojure destructuring

6
推荐指数
1
解决办法
323
查看次数

尝试使用 jdbc 从 clojure 连接到 postgresql 时,密码验证失败

我正在 Clojure 中学习 Web 开发,但我根本不是 PostgreSQL 或 JDBC 方面的专家。

我正在阅读“使用 Clojure 进行 Web 开发”一书,但由于无法连接到 PostgreSQL 数据库而被卡住了,尽管我相信我已经一步一步地遵循了教程。

我连接到 psql

sudo -u postgres psql
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个密码为“admin”的管理员用户

postgres=# CREATE USER admin WITH PASSWORD 'admin';
CREATE ROLE
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个名为报告的数据库:

postgres=# CREATE DATABASE reporting OWNER admin;
CREATE DATABASE
Run Code Online (Sandbox Code Playgroud)

至今没有投诉。

然后从我的 clojure 代码中,我尝试连接到数据库并创建一个表:

(ns reporting-example.models.db
  (:require [clojure.java.jdbc :as sql]))

;defining the db connection
(def db 
  {:subprotocol "postgresql"
   :subname "//localhost/reporting"
   :user "admin"
   :password "admin"})

;function for creating an 'employee' table
(defn create-employee-table []
  (sql/create-table :employee
                    [:name "varchar(50)"]
                    [:occupation "varchar(50)"] …
Run Code Online (Sandbox Code Playgroud)

postgresql jdbc clojure

5
推荐指数
1
解决办法
5109
查看次数

当协议调用表包含<!时,core.async go block无法编译 宏(multimethod' -item-to-ssa'无法调度:protocol-invoke)

go当我偶然发现一个奇怪的编译错误时,我正在实现一个涉及core.async 块的函数:

CompilerException java.lang.IllegalArgumentException: 
No method in multimethod '-item-to-ssa' for dispatch value: :protocol-invoke, 
compiling:(NO_SOURCE_PATH:2:3) 
Run Code Online (Sandbox Code Playgroud)

我尝试了一点尝试去除问题,发现它非常通用.说我有任何协议MyProtocol:

(defprotocol MyProtocol
  (do-something [this param] "some method"))
Run Code Online (Sandbox Code Playgroud)

以下代码将无法编译,失败,上面显示的异常:

(defn uncompilable! [me ch] 
  (go 
    (do-something me (<! ch)) ;; apparently, it hurts to use <! in a protocol method invocation 
    ))
Run Code Online (Sandbox Code Playgroud)

但是,以下2将编译没有任何问题:

(defn compilable! [me ch] 
  (let [call-it #(do-something me %)] ; wrapping the protocol call in a function
    (go 
     (call-it (<! ch))
     )))

(defn compilable-2! [me ch] 
  (go 
    (let [my-value (<! …
Run Code Online (Sandbox Code Playgroud)

macros compilation clojure multimethod core.async

5
推荐指数
1
解决办法
239
查看次数

为什么这个clojurescript构建配置文件在本地工作但不在Heroku上工作?

以下是在prod本地和在uberjar中用于Heroku部署的配置:

{:source-paths ["src/cljs"]
                :compiler {:output-to "resources/public/js/main.js"
                           :optimizations :advanced
                           :cache-analysis true
                           :static-fns true
                           :elide-asserts true
                           :pretty-print false
                           :externs ["jquery/jquery-externs.js" "public/vendor/js/bootstrap.min.js"]
                           :preamble ["jquery/jquery-2.1.1.min.js"
                                      "public/vendor/js/bootstrap.min.js"
                                      "reagent/react.js"]}}
Run Code Online (Sandbox Code Playgroud)

但是externs为Heroku部署启用了指令,我收到此错误:

Jan 14, 2015 12:24:24 PM com.google.javascript.jscomp.LoggerErrorManager println
       SEVERE: ERROR - Duplicate extern input: /tmp/build_a17563dbd2ef7be695204764be886d91/resources/jquery/jquery-externs.js

       Jan 14, 2015 12:24:24 PM com.google.javascript.jscomp.LoggerErrorManager println
       SEVERE: ERROR - Duplicate extern input: /tmp/build_a17563dbd2ef7be695204764be886d91/resources/public/vendor/js/bootstrap.min.js

       Jan 14, 2015 12:24:24 PM com.google.javascript.jscomp.LoggerErrorManager printSummary
       WARNING: 2 error(s), 0 warning(s)
       ERROR: JSC_DUPLICATE_EXTERN_INPUT. Duplicate extern input: /tmp/build_a17563dbd2ef7be695204764be886d91/resources/jquery/jquery-externs.js at (unknown source) line (unknown line) …
Run Code Online (Sandbox Code Playgroud)

heroku clojurescript

5
推荐指数
1
解决办法
548
查看次数

使用Protractor设置角度模型

我正在尝试使用Protractor在我的网站上模拟用户故事.

用户必须输入使用自动完成的输入.在现实生活中,用户必须在输入中键入一些文本,然后用鼠标或更自然地用她的向下键来选择正确的命题.

问题是我似乎无法用Protractor模拟它.element.sendKeys只是不允许你这样做.我已经尝试了十几种不同的方式,它最多会产生不可预测的结果.

所以我想直接操纵ng-model behing我的输入.有没有办法从Protractor访问元素的范围并调用函数/ set属性?

这是我的问题的简化版本:

查看:

<div ng-controller="MyController"> 
  <input id="my-input" ng-model="myModel"/>
</div>
Run Code Online (Sandbox Code Playgroud)

控制器:

 myModule.controller('MyController', ['$scope', function($scope){
   $scope.myModel = "";
   //[...]
 }]);
Run Code Online (Sandbox Code Playgroud)

e2e量角器测试:

describe("setting myModel to a fixture value", function(){
  it("should set myModel to 'a test value'", function(){
    var myInput = element('my-input');
    // Now what?
  });
});
Run Code Online (Sandbox Code Playgroud)

javascript angularjs protractor

4
推荐指数
1
解决办法
5337
查看次数

灯表:括号不自动关闭

我正在尝试使用paredit编辑Light Table上的Clojure/ClojureScript文件,但插件似乎不起作用.当我打开括号时,它没有关闭.

但是插件安装如插件列表所示.

我错过了一些配置步骤,还是错误?

(在撰写本文时,我刚刚安装了最新版本,但没有触及配置).

paredit lighttable

4
推荐指数
1
解决办法
1533
查看次数

React适用于多页面应用吗?

我目前正在开发单页应用程序(在这种情况下是AngularJS),但随着它的发展,我发现将它重构为多页面应用程序越来越诱人.

但是,我仍然需要能够在客户端上拥有复杂的动态UI(这不仅需要DOM操作,还需要了解我的信息模型).

我知道大多数人都会使用jQuery; 我担心它不会让我达到我想要的程度,而且我想知道ReactJS是否适合这项工作(好吧,当你经营一家小公司,而不是Facebook).

javascript client reactjs

3
推荐指数
1
解决办法
1880
查看次数