小编Mar*_*oot的帖子

在具有多个容器实例的Docker容器中使用Rails运行迁移

我已经看到很多为Rails应用程序制作Docker容器的例子.通常,他们运行rails服务器并拥有运行迁移/设置的CMD,然后启动Rails服务器.

如果我同时生成其中5个容器,Rails如何处理尝试启动迁移的多个进程?我可以看到Rails检查通用查询日志中的当前模式版本(它是一个MySQL数据库):

 SELECT `schema_migrations`.`version` FROM `schema_migrations`
Run Code Online (Sandbox Code Playgroud)

但是如果在不同的Rails实例上同时发生这种情况,我可以看到竞争条件.

考虑到DDL在MySQL中不是事务性的,并且我在运行迁移时看不到通用查询日志中发生任何锁定(除了每次迁移事务),看起来并行启动它们是个坏主意.事实上,如果我在本地启动三次,我可以看到两个rails实例在尝试创建表时崩溃,因为它已经存在,而第三个rails实例很快就完成了迁移.如果这是一个将某些东西插入数据库的迁移,那将是非常不安全的.

那么运行一个运行迁移/设置的单个容器然后产生(例如)一个Unicorn实例然后生成多个rails工作人员会更好吗?

我是否应该产生N个轨道容器和一个运行迁移的"迁移容器"然后退出?

有更好的选择吗?

mysql ruby-on-rails database-migration rails-migrations docker

30
推荐指数
2
解决办法
1万
查看次数

版本Rails 3 API的正确方法

我有一个Rails 3引擎,可以为大约20个控制器公开API路由.这些控制器代表了不同嵌套级别的几种不同资源,并且有超过500种rspec测试.API在v1上使用名称空间和基于版本标头的路由约束进行版本控制,默认为v1.这是很多博客文章中描述的版本控制系统,似乎是最佳实践.

这些博客文章中没有描述的是您如何实际管理推出新版本.我必须对单个控制器的输出进行重大更改.此更改通过更改其中一个JSON值的结构来影响对象的JSON响应.这将导致该控制器的索引,显示和编辑视图中断.

很明显,我可以将所有内容复制app/api/v1app/api/v2[1].然后,我可以对我的新v2序列化器进行单一更改.我现在已经为API的第2版获得了大量重复代码,几乎没有任何更改.我需要在两个地方维护代码.我可能不得不让我的整个rspec套件在版本2控制器以及版本1控制器上运行,并对v2序列化器进行一些额外的测试.这听起来像一个可怕的想法.对于从v1控制器继承的v1命名空间中的每个未更改的控制器,我们可以有一些stub v2控制器.这听起来也不是很好.

我能想到的最好的选择是在我的v2 API中有一个单独的控制器(在这种情况下可能只是一个串行器),有一些路由魔术可以检查是否存在所需版本的控制器并通过以前的版本回退直到找到一个.序列化程序版本也应具有类似的魔力,以检查此版本是否存在,并在找到之前回退.这引入了最少的额外代码,并且不会立即使我的测试套件的持续时间翻倍.它需要能够将函数直接插入到rails路由逻辑中,然后才能为我丢失的v2控制器返回404.可能我可以根据文件系统分析所有控制器的命名空间,并在rails启动时使用回退生​​成路由,但是很难明确地从先前版本的API中删除路由.

似乎我们需要继续为每个非附加功能/输出格式进行更改,直到每个先前版本被弃用和删除为止.我们有一个额外的未发布的API,包含约4000个控制器,涵盖~4000个规格.当我们开始从外部记录并发布这些内容时会发生什么?

除了按照我们发布功能的速率批量处理API更改之外,其他人如何管理?上面的想法是否可行?有没有更好的办法?

[1]问题一.我们使用ActiveModel :: Serializers来生成JSON响应.ActiveModel :: Serializers 不支持API版本控制,尽管似乎有一种方法可以使用ruby魔法来选择正确的类.

api json ruby-on-rails rails-api active-model-serializers

11
推荐指数
2
解决办法
527
查看次数

通过SWIG处理Java中的C++异常

我正在尝试使用SWIG将C++类包装到Java类中.这个C++类有一个抛出异常的方法.

我有三个目标,虽然我按照我的理解遵循了手册,但目前都没有这个目标:

  • 让Java类声明throws <exceptiontype>抛出C++的方法
  • 获取SWIG生成的Exception类进行扩展 java.lang.Exception
  • Exception.getMessage()在生成的SWIG类中覆盖.

似乎问题的根源似乎是我的typemaps未被应用,因为上述情况都没有发生.我做错了什么?

最小的例子如下.C++不需要编译,我只对生成的Java感兴趣.异常的类是无关紧要的,下面的代码使用IOException只是因为文档使用它.所有代码都是根据以下示例改编的:

C++头文件(test.h):

#include <string>

class CustomException {
private:
  std::string message;
public:
  CustomException(const std::string& message) : message(msg) {}
  ~CustomException() {}
  std::string what() {
    return message;
  }
};

class Test {
public:
  Test() {}
  ~Test() {}
  void something() throw(CustomException) {};
};
Run Code Online (Sandbox Code Playgroud)

SWIG .i文件:

%module TestModule
%{
#include "test.h"
%}

%include "std_string.i" // for std::string typemaps
%include "test.h"

// Allow C++ exceptions to be handled in Java
%typemap(throws, …
Run Code Online (Sandbox Code Playgroud)

c++ java swig

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

CMake FindThreads.cmake 找不到我的 pthreads.h 标头

我正在使用android-cmake为 Android 编译应用程序。这实质上创建了一个 CMake 工具链文件,用于使用 Android 的 NDK 提供的工具链。

此相关问题一样,我的 CMakeLists.txt 文件中的以下行有问题:

find_package(Threads REQUIRED)
Run Code Online (Sandbox Code Playgroud)

头文件位于

~/Android/android-ndk-r7/platforms/android-8/arch-arm/usr/include/pthread.h
Run Code Online (Sandbox Code Playgroud)

库文件位于

~/Android/android-ndk-r7/platforms/android-8/arch-arm/usr/lib/libthread_db.so
Run Code Online (Sandbox Code Playgroud)

问题是 FindThreads.cmake 调用CHECK_INCLUDE_FILES("pthread.h", CMAKE_HAVE_PTHREAD_H),这似乎不费心去检查那个目录。

根据CMake 的有用变量 wiki 页面, CMAKE_INCLUDE_PATH允许设置标题搜索路径,CMAKE_LIBRARY_PATH允许设置库搜索路径,并且CMAKE_PREFIX_PATH似乎为 find_package 提供了两者。

但是,尽管我是否在运行 cmake 之前设置了环境变量...

export CMAKE_INCLUDE_PATH=~/Android/android-ndk-r7/platforms/android-8/arch-arm/usr:~/Android/android-ndk-r7/platforms/android-8/arch-arm/usr/include
Run Code Online (Sandbox Code Playgroud)

...或者我是否直接在 CMakeLists.txt 中设置它们...

if(ANDROID)
    set(CMAKE_INCLUDE_PATH
        ${ANDROID_NDK_SYSROOT}/usr
        ${ANDROID_NDK_SYSROOT}/usr/include
        ${CMAKE_INCLUDE_PATH}
    )

    set(CMAKE_LIBRARY_PATH
        ${ANDROID_NDK_SYSROOT}/usr
        ${ANDROID_NDK_SYSROOT}/usr/lib
        ${CMAKE_LIBRARY_PATH})

    set(CMAKE_PREFIX_PATH
        ${ANDROID_NDK_SYSROOT}
        ${CMAKE_PREFIX_PATH})

    message(${ANDROID_NDK_SYSROOT})
    message(${CMAKE_INCLUDE_PATH})

endif()

find_package(Threads REQUIRED)
Run Code Online (Sandbox Code Playgroud)

...(这确实被执行,消息被打印),以及哪里${ANDROID_NDK_SYSROOT}包含

/Users/martin/Android/android-ndk-r7/platforms/android-8/arch-arm
Run Code Online (Sandbox Code Playgroud)

我仍然收到消息

找不到线程(丢失:Threads_FOUND)

有人对我做错了什么有任何建议吗?

android cmake

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

如何从 Rails 引擎的 rspec 测试中的父应用程序访问模型?

我有一个 Rails 应用程序,里面有一个可安装的引擎。我目前正在为可安装引擎设置 rspec 测试。这些需要从父应用程序访问模型和助手。我知道这里存在一些耦合,但这不是可重用的组件,并且引擎用于提供与父应用程序分开的附加功能。

我可以在从命令创建的虚拟应用程序中运行这些测试rails new plugin,但这无法访问父应用程序模型。

如何配置我的规范助手,以便它从父应用程序加载模型和配置设置?理想情况下,这将包括父应用程序的spec_helper.rb.

我相信我应该能够使用我的父应用程序而不是虚拟应用程序,但到目前为止尚未成功。当尝试运行我的规范时,我被迫将父应用程序中的所有 gem 包含到我的引擎中Gemfile,并在父应用程序中包含其他已安装引擎的 s 。NameError

rspec ruby-on-rails ruby-on-rails-3.2

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