2013-06-02 41 views
10

Đằng sau điều này (không quá nhiều tôi thừa nhận ...) funny câu hỏi là một câu hỏi thực sự về một workaround tôi sử dụng mà không thực sự hiểu làm thế nào nó hoạt động.Điều gì sẽ xảy ra khi tôi "ngủ" trong GAS? (thực hiện giới hạn thời gian giải quyết)

Lần đầu tiên một mô tả ngắn gọn về trường hợp sử dụng của tôi, tất cả điều này đang xảy ra trong một tài liệu ràng buộc UiApp hiển thị trong thanh bên:

tôi phải tạo ra và gửi qua email một vài trăm tài liệu trong một ứng dụng mail merge viết bằng GAS. Phải mất tất nhiên quá dài để được xử lý trong một lô mà không đạt đến giới hạn thời gian thực hiện 5 phút vì vậy tôi đã thử một vài cách giải quyết khác nhau để hoàn thành công việc:

  1. sử dụng dấu thời gian (được lưu trữ trong ScriptProperties) khi Tôi bắt đầu quá trình và khi tôi đạt đến giá trị được xác định trước gần giới hạn, tôi lưu trữ các giá trị hiện tại (con trỏ, vars hữu ích ...) và quay lại giao diện người dùng yêu cầu người dùng tiếp tục (hoặc không). Điều đó hoạt động khá tốt nhưng cần một hành động của con người để hoàn thành toàn bộ nhiệm vụ.
  2. Vì vậy, tôi thiết lập giải pháp bằng trình kích hoạt bộ hẹn giờ mà tôi tạo trong cuộc gọi trình xử lý đầu tiên và trình kích hoạt này gọi hàm tạo/gửi tài liệu. Điều này cũng hoạt động tốt nhưng hàm trigger được gọi là không thể tương tác với giao diện người dùng vì dường như chỉ có các hàm xử lý mới có thể cập nhật giao diện người dùng. Vấn đề là tôi không thể hiển thị tiến trình cũng như không dễ dàng hiển thị khi quá trình kết thúc. Sau đó, tôi nhớ một ứng dụng nhỏ đã viết một số thời gian trước đây chỉ để cho vui: đó là một bộ đếm thời gian sử dụng một hộp kiểm như một trình kích hoạt trình xử lý máy chủ (từ một ý tưởng được đề xuất từ ​​lâu bởi Romain Vialard trên diễn đàn cũ của Google) và quyết định để thử mẹo này trong quá trình gửi thư của tôi.

Nó hoạt động hoàn hảo, tôi xử lý 40 lô tài liệu là mỗi cuộc gọi (trong khoảng 3 phút) sau đó tạm dừng một lúc và bắt đầu lại cho đến khi hoàn thành. Mỗi cuộc gọi được kích hoạt bởi trình quản lý máy chủ được liên kết hộp kiểm, hộp kiểm tự thay đổi trong hàm xử lý, tạo trình kích hoạt của riêng nó theo cách này.

Câu hỏi của tôi (cuối cùng ;-) là: biết rằng toàn bộ quá trình có thể mất 30 đến 60 phút chính xác như thế nào là có thể? Làm cách nào/tại sao các chức năng xử lý máy chủ này được coi là nhiều quá trình vì chúng được tạo từ bên trong chính hàm?

Tôi hy vọng tôi đủ rõ ràng, (mà tôi nghi ngờ vì nó là một chút nhầm lẫn trong tâm trí của tôi :-)

tôi tham gia dưới đây mã của ứng dụng thử nghiệm đồng hồ mà đã cho tôi ý tưởng, nó có thể sẽ giúp mọi thứ dễ hiểu hơn.

function doGet() { 
    var app = UiApp.createApplication().setTitle('Counter/Timer'); 
    var Panel = app.createAbsolutePanel().setStyleAttribute('padding','35'); 
    var counter = app.createHTML().setId('counter').setHTML('<B>Timer = wait</B>').setStyleAttribute('fontSize','40px');// set start display 
    var clo = app.createTextBox().setName('clo').setId('clo').setValue('0').setVisible(false);//set start value in seconds 
    var handler1 = app.createServerHandler('doSomething').addCallbackElement(Panel); 
    var chk1 = app.createCheckBox('test1').addValueChangeHandler(handler1).setVisible(true).setId('chk1').setVisible(false); 
    app.add(Panel.add(chk1).add(counter).add(clo)); 
    chk1.setValue(true,true);// start the process 
    return app} 

function doSomething(e) { 
    var app = UiApp.getActiveApplication(); 
    var xx = Number(e.parameter.clo); 
    var disp = app.getElementById('counter') 
    xx++ ;// replace by xx-- to count downwards 
    if(xx>600){ // 10 minutes timeout for example 
    disp.setHTML('<B> GAME OVER ;-)</B>').setStyleAttribute('fontSize','80px').setStyleAttribute('color','RED') 
    return app 
    } 
    var cnt = app.getElementById('clo').setValue(xx) 
    disp.setHTML('<B>'+T(xx)+'</B>') 
    Utilities.sleep(1000); // instead of sleeping do something ! 
// below comes the "active" part 
    var chk1 = app.getElementById('chk1').setValue(false,false) 
    var chk1 = app.getElementById('chk1').setValue(true,true) 
    return app; 
} 

function T(val){ 
    var min = parseInt(val/60); 
    var sec = val-(60*min); 
    if(sec<10){sec='0'+sec} 
    if(min<10){min='0'+min} 
    var st = '> '+min+':'+sec 
    return st 
} 

enter image description here

+0

Trong khi câu hỏi này sử dụng Dịch vụ giao diện người dùng không dùng nữa, bạn có thể thực hiện cùng một hiệu ứng bằng cách sử dụng Dịch vụ HTML. [Bruce McPherson đã viết blog về nó.] (Http://ramblings.mcpher.com/Home/excelquirks/htmlservice/parallel) – Mogsdad

Trả lời

10

Những tuyên bố rằng bộ xử lý máy chủ cuộc gọi chức năng không phải là quá trình độc lập vì họ "được tạo ra từ bên trong hàm chính nó" là không hoàn toàn đúng.

Bạn đã thiết lập phần tử hộp kiểm chk1 với trình xử lý máy chủ doSomething. Bất cứ khi nào hộp kiểm được chọn, thì sự kiện là được gửi tới máy chủ. (... và tập lệnh của bạn đang gây ra các sự kiện đó với mọi cuộc gọi chk1.setValue()) checkBox và mã giao diện người dùng xung quanh đang chạy trong trình duyệt của bạn - nhấp vào "hiển thị nguồn" hoặc sử dụng trình khám phá để xem những gì được máy chủ google phân phát cho trình duyệt của bạn. (Cảnh báo - nó bị làm xáo trộn.Nhưng bạn có thể nhận ra một số dây của bạn, và từ đó client-side code của bạn)

Dưới đây là những gì chúng ta đang nói trong tài liệu cho Class ServerHandler:.

Khi một ServerHandler được gọi, chức năng nó đề cập đến được gọi trên máy chủ Apps Script trong tập lệnh "mới".

Đó là chìa khóa để kéo dài thời gian điều hành của bạn: mỗi kết quả sự kiện cử trong invocation của doSomething() trong bối cảnh hoạt động hoàn toàn mới - nó giống như bạn đã mở trình biên tập kịch bản trong một trình duyệt khác nhau, và nhấp "chạy" trên kịch bản của bạn. Tập lệnh "mới" không có quyền truy cập vào các giá trị var của lần chạy trước đó ... nhưng nó cũng được cung cấp bộ hạn chế hoạt động của riêng nó, bao gồm cả bộ tính giờ.

PS: Bạn nên đảm bảo rằng trình xử lý phía máy chủ là "an toàn luồng" bằng cách sử dụng Khóa, vì bạn đang truy cập các tài nguyên được chia sẻ có thể được truy cập bởi nhiều phiên bản gọi lại doSomething(). Liên quan đến điều đó, nó có thể đạt giới hạn khác với kịch bản này:

Screenshot - error

Chỉ cần cho vui, tôi nhận xét ra .setVisible(false) trên chk1, vì vậy các hộp kiểm sẽ được hiển thị. Sau đó tôi nhanh chóng bấm vào nó vài chục lần. Màn hình hiển thị thời gian hết hàng, và cuối cùng lỗi trên xuất hiện. (phút sau) Đó là một tình huống nhân tạo, tất nhiên, nhưng vẫn là một trạng thái lỗi dễ dàng tránh được.

PPS: Tôi tự hỏi liệu người ta có thể sử dụng cùng một kỹ thuật để gửi nhiều trình xử lý phía máy chủ song song, và do đó giảm thời gian trôi qua để hoàn thành toàn bộ công việc?

+1

Cảm ơn câu trả lời rõ ràng này, tôi biết bạn sẽ thích nó ;-) btw, xác nhận đó là một cách tốt để giải quyết thời gian thực hiện giới hạn ... Tôi sẽ thực hiện tính năng khóa quá ngay cả khi tôi chưa bao giờ gặp bất kỳ vấn đề tương tranh nào cho đến bây giờ. –

+0

wow cách tiếp cận thú vị. Tôi sẽ phải sử dụng cái này. Hiện tại tôi đang sử dụng trình kích hoạt tạo lập trình để bắt chước Hàng đợi nhiệm vụ và luồng ....... –

+0

cách tiếp cận thú vị. tuy nhiên nó có vẻ như cho điều này để làm việc cho các trường hợp sử dụng luồng, người dùng phải thực hiện một số hành động ngay cả khi nó là một sự kiện di chuột qua. tôi không thể kích hoạt serverhandler chỉ bởi đức hạnh của tải UiApp trong trình duyệt ....... –

Các vấn đề liên quan